marshall with xjc created nested classes

老子叫甜甜 提交于 2019-12-05 23:36:00

问题


<ProductInformation Context="GL">
 <Assets>
  <Asset ID="assetID" UserTypeID="ID">
    <Name>name</Name>
    <Reference ClassificationID="id"/>
      <Values>
        <Value AttributeID="ID">Value1</Value>
        <Value AttributeID="ID">Value2</Value>
          <MultiValue AttributeID="attributeID">
             <Value>value3a</Value>
             <Value>value3b</Value>
          </MultiValue>
     </Values>
   </Asset>
 </Assets>

 <Products>....</Products>

</ProductInformation>

I used this xml->xsd and xjc to create classes from it.

Now I want to create my ProductInformation object,and marshall it.

My problem is xjc create 3 classes and a objectfactory, and some nested classes inside ProductInformation. When I look at the avaliable methods I mostly see getters instead of setters.

"Asset" class has no such methods like;

asset.setValues(List<Value> values)

Also I ended up writing funny code like this;

ProductInformation.Assets.Asset.Values.MultiValue multivalue=new ProductInformation.Assets.Asset.Values.MultiValue();

Is this normal with Jaxb?


回答1:


The way JAXB normally handles multi valued properties is to provide just a getter and no setter for the List<Whatever>, which returns a mutable list - you're supposed to call the getter to retrieve an initially-empty list and then create the member objects for this list using new in the normal way and add them directly to the list. You can new a static nested class in exactly the same way as a top-level one.

Single-valued properties (not lists) should have been generated with both getter and setter.




回答2:


The answer given by Ian Roberts is the correct one. I am giving this one to provide some additional information for those people interested in not having inner classes.

XML Schema (schema.xsd)

If JAXB classes are generated from the following XML schema, both the resulting Customer and Employee classes will contain a static nested class called Address (because each contains their own definition of an address). This is in fact why static nested classes are used to avoid name conflict problems.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
    targetNamespace="http://www.example.org/company"
    xmlns="http://www.example.org/company"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"> 

    <xsd:element name="customer">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="address">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="street" type="xsd:string"/>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="employee">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="address">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="road" type="xsd:string"/>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

JAXB Binding File (binding.xml)

A bindings file is used to customize the schema to Java generation. You can specify that everything should be a top level class with localScoping="top-level". When you do this you must make sure to resolve any potential name conflicts.

<jaxb:bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
    <jaxb:bindings schemaLocation="company.xsd">
        <jaxb:bindings node="//xsd:element[@name='employee']/xsd:complexType/xsd:sequence/xsd:element[@name='address']/xsd:complexType">
            <jaxb:class name="EmployeeAddress"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

XJC Call

Below is an example of specifying a bindings file when using the XJC command to generate Java classes from an XML schema.

xjc -b binding.xml schema.xsd

For More Information

  • http://blog.bdoughan.com/2011/07/jaxb-xjc-and-nested-classes.html



回答3:


This is actually just a comment to Blaise Doughan's answer but I want to post the xml.

If you work with a more complex xsd and the path in the node attribute is getting too long, you can:

<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
    <jaxb:bindings schemaLocation="company.xsd">
        <jaxb:bindings node="//xsd:element[@name='employee']">
            ....
                <jaxb:bindings node=".//xsd:element[@name='address']/xsd:complexType">
                    <jaxb:class name="EmployeeAddress"/>
                </jaxb:bindings>
            ....
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>


来源:https://stackoverflow.com/questions/13414407/marshall-with-xjc-created-nested-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!