包括 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;
}
}
这是否接近您的需要?
我有两个 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;
}
}
这是否接近您的需要?