Reputation: 2672
I have two XSDs where one XSD contains an element that can contain elements from the second one. Basically, XSD 1 has an element "etta" which can contain any element from XSD 2.
I used xjc to generate the classes, and when it is deserialized, the Meta element contains the elements from XSD 2 as JAXBElements instead of the actual classes generated from XSD 2. I included both sets of classes into my program, and the package-info is correct.
This is how I defined my XSD. I imagine the problem is my "any" element.
<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>
So basically what I want is the element to mean "Here goes one or more elements that are defined in XSD2" and would like jaxb to unmarshall it.
How should I change my XSD to help jaxb deserialize contents of Meta using elements from XSD2?
--edit-
This is what xjc generated for the 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;
}
}
-- EDIT original XSD2 (changed NS to match the question) --
<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>
-- this is how the Meta is being used in my 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" />
Upvotes: 0
Views: 728
Reputation: 431
How about sth. like this:
Inserting all possible elements from your second xsd into the sequence while defining the minOccurs and maxOccurs in the sequence instead of the elements themselves. (The code is from here - Example 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>
Another option would require changing the second xsd a little bit:
instead of line 2-4 looking like this:
<xs:element name="MetInf">
<xs:complexType>
<xs:sequence>
they would have to look like this:
<xs:complexType name="MetInf">
<xs:sequence>
And the NS1.xsd would look like this:
<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>
when running xjc with firstSchema.xsd and NS2.xsd in the same directory the following classes are generated:
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
The Meta class I get for the firstSchema.xsd looks like this:
public class Meta {
@XmlElement(required = true)
protected List<MetInf> metaInf;
public List<MetInf> getMetaInf() {
if (metaInf == null) {
metaInf = new ArrayList<MetInf>();
}
return this.metaInf;
}
}
Is that anywhere near what you need?
Upvotes: 1