7
<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>

我使用这个 xml->xsd 和 xjc 从它创建类。

现在我想创建我的 ProductInformation 对象,并对其进行编组。

我的问题是 xjc 创建 3 个类和一个 objectfactory,以及 ProductInformation 中的一些嵌套类。当我查看可用的方法时,我主要看到的是 getter 而不是 setter。

“资产”类没有这样的方法;

asset.setValues(List<Value> values)

我最后也写了这样有趣的代码;

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

Jaxb 这正常吗?

4

3 回答 3

6

伊恩·罗伯茨给出的答案是正确的。我给出这个是为了为那些对没有内部类感兴趣的人提供一些额外的信息。

XML 模式 (schema.xsd)

如果 JAXB 类是从以下 XML 模式生成的,则生成的类CustomerEmployee类都将包含一个名为的静态嵌套类Address(因为每个类都包含它们自己的地址定义)。这就是为什么使用静态嵌套类来避免名称冲突问题的原因。

<?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.xml)

绑定文件用于将模式定制为 Java 生成。您可以指定一切都应该是一个顶级类localScoping="top-level"。执行此操作时,您必须确保解决任何潜在的名称冲突。

<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 呼叫

下面是使用 XJC 命令从 XML 模式生成 Java 类时指定绑定文件的示例。

xjc -b binding.xml schema.xsd

了解更多信息

于 2012-11-16T11:15:11.703 回答
5

JAXB 通常处理多值属性的方式是只为 提供一个 getter 而没有 setter List<Whatever>,它返回一个可变列表 - 您应该调用 getter 来检索一个最初为空的列表,然后为此列表创建成员对象以new正常方式使用并将add它们直接添加到列表中。您可以new使用与顶级类完全相同的方式创建静态嵌套类。

应该使用 getter 和 setter 生成单值属性(不是列表)。

于 2012-11-16T10:17:03.303 回答
1

这实际上只是对 Blaise Doughan 的回答的评论,但我想发布 xml。

如果您使用更复杂的 xsd 并且node属性中的路径变得太长,您可以:

<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>
于 2018-07-27T11:29:31.760 回答