包括 Jaxb 和解组 XSD

Jaxb and unmarshalling included XSD

我有两个 XSD,其中一个 XSD 包含一个可以包含第二个元素的元素。基本上,XSD 1 有一个元素 "etta",它可以包含 XSD 2 中的任何元素。

我使用 xjc 生成 classes,当它被反序列化时,Meta 元素包含来自 XSD 2 的元素作为 JAXBElements 而不是实际生成的 classes来自 XSD 2. 我将两组 classes 都包含在我的程序中,并且 package-info 是正确的。

这就是我定义 XSD 的方式。我想问题出在我的 "any" 元素上。

<xs:schema xmlns="NS1" elementFormDefault="qualified"
           xmlns:ns1="NS2"
           targetNamespace="NS1" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:import  namespace="NS2" schemaLocation="./NS2.xsd" />

    <xs:complexType name="Meta">
        <xs:sequence>
            <xs:any  namespace="NS2" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
...
</xs:schema>

所以基本上我想要的是表示 "Here goes one or more elements that are defined in XSD2" 的元素,并希望 jaxb 解组它。

我应该如何更改 XSD 以帮助 jaxb 使用 XSD2 中的元素反序列化 Meta 的内容?

--编辑-

这是 xjc 为 Meta 生成的 class:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Meta", propOrder = {
    "any"
})
public class Meta
    extends BaseObject
{

    @XmlAnyElement(lax = true)
    protected List<Object> any;

    public List<Object> getAny() {
        if (any == null) {
            any = new ArrayList<Object>();
        }
        return this.any;
    }

}

-- 编辑原始 XSD2(更改 NS 以匹配问题)--

<xs:schema xmlns="NS2" elementFormDefault="qualified" targetNamespace="syncml:NS2" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="MetInf">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="FieldLevel" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Format" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Type" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Mark" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Size" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Anchor" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Version" />
                <xs:element minOccurs="0" maxOccurs="1" ref="NextNonce" />
                <xs:element minOccurs="0" maxOccurs="1" ref="MaxMsgSize" />
                <xs:element minOccurs="0" maxOccurs="1" ref="MaxObjSize" />
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="EMI" />
                <xs:element minOccurs="0" maxOccurs="1" ref="Mem" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="FieldLevel">
        <xs:complexType />
    </xs:element>
    <xs:element name="Format" type="xs:string" />
    <xs:element name="Type" type="xs:string" />
    <xs:element name="Mark" type="xs:string" />
    <xs:element name="Size" type="xs:string" />
    <xs:element name="Anchor">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="Last" />
                <xs:element ref="Next" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Last" type="xs:string" />
    <xs:element name="Next" type="xs:string" />
    <xs:element name="Version" type="xs:string" />
    <xs:element name="NextNonce" type="xs:string" />
    <xs:element name="MaxMsgSize" type="xs:string" />
    <xs:element name="MaxObjSize" type="xs:string" />
    <xs:element name="EMI" type="xs:string" />
    <xs:element name="Mem">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="SharedMem" />
                <xs:element ref="FreeMem" />
                <xs:element ref="FreeID" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="FreeID" type="xs:string" />
    <xs:element name="FreeMem" type="xs:string" />
    <xs:element name="SharedMem">
        <xs:complexType />
    </xs:element>
</xs:schema>

-- 这就是 Meta 在我的 XSD1:

中的使用方式
<xs:element name="TargetRef" type="xs:string" />
  <xs:element name="VerDTD" type="xs:string" />
  <xs:element name="VerProto" type="xs:string" />
  <xs:element name="Item">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="1" ref="Target" />
        <xs:element minOccurs="0" maxOccurs="1" ref="Source" />
        <xs:element minOccurs="0" maxOccurs="1" ref="SourceParent" />
        <xs:element minOccurs="0" maxOccurs="1" ref="TargetParent" />
        <xs:element minOccurs="0" maxOccurs="1" ref="Meta" />
        <xs:element minOccurs="0" maxOccurs="1" ref="Data" />
        <xs:element minOccurs="0" maxOccurs="1" ref="MoreData" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Meta" type="xs:string" />
  <xs:element name="Correlator" type="xs:string" />
  <xs:element name="Data" type="xs:string" />

怎么样……像这样:

将第二个 xsd 中的所有可能元素插入到序列中,同时在序列中定义 minOccurs 和 maxOccurs 而不是元素本身。 (代码来自here-例2)

<xs:element name="Meta">
    <xs:complexType>
        <xs:sequence minOccurs="1" maxOccurs="unbounded">
            <xs:element name="elements" type="ns1:typeA"/>
            <xs:element name="from" type="ns1:typeB"/>
            <xs:element name="NS2" type="ns1:typeC"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

另一个选项需要稍微更改第二个 xsd:

而不是第 2-4 行看起来像这样:

<xs:element name="MetInf">
    <xs:complexType>
        <xs:sequence>

他们必须看起来像这样:

        <xs:complexType name="MetInf">
            <xs:sequence>

NS1.xsd 看起来像这样:

<xs:schema 
    xmlns="NS1"
    elementFormDefault="qualified"
    targetNamespace="NS1" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ns1="NS2">

<xs:import  namespace="NS2" schemaLocation="NS2.xsd" />

<xs:complexType name="Meta">
    <xs:sequence>
        <xs:element name="metaInf" type="ns1:MetInf" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

当 运行 xjc 与 firstSchema.xsd 和 NS2.xsd 在同一目录中时,生成以下 classes:

ns2/Anchor.java
ns2/FieldLevel.java
ns2/Mem.java
ns2/MetInf.java
ns2/ObjectFactory.java
ns2/SharedMem.java
ns2/package-info.java
ns1/Meta.java
ns1/ObjectFactory.java
ns1/package-info.java

我为 firstSchema.xsd 得到的 Meta class 看起来像这样:

public class Meta {

@XmlElement(required = true)
protected List<MetInf> metaInf; 
public List<MetInf> getMetaInf() {
    if (metaInf == null) {
        metaInf = new ArrayList<MetInf>();
    }
    return this.metaInf;
}
}

这是否接近您的需要?