I’am using JIBX in order to map my XML data to Java objects. This perfectly works when the XML is containing only one target namespace. Unfortunately, the requirements have changed and now I get XML data with two different namespaces inside.
Example:
<a:foo>
<b:bar>Simple Example</b:bar>
</a:foo>
My question is, how to write a xsd that yields two different target namespaces?
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="namespace_of_a"
xmlns:a="namespace_of_a"
xmlns:b="namespace_of_b"
elementFormDefault="qualified">
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<!-- this won't work, because b is part of a different namespace -->
<xs:attribute type="xs:string" use="required" name="bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I already tried:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="namespace_of_a"
xmlns:a="namespace_of_a"
xmlns:b="namespace_of_b"
elementFormDefault="qualified">
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<!-- this won't work, because jibx is reporting that targetNamespace is an unknown attribute -->
<xs:attribute targetNamespace="namespace_of_b" type="xs:string" use="required" name="bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Please help. I’m not sure whether this is possible in general or not? Thanks in advance!
Yes, it’s possible. It’s one of the core scenarios XSD was designed to handle.
(1) Write separate schema documents for each namespace involved, with that namespace given as the
targetNamespaceof thexs:schemaelement.If your
a:fooelement can accept only ab:barelement as a child, then in the schema document forayou will want to import namespaceb, so that the content model fora:foocan refer to elementb:bar. For example, modify your sample schema document to include:(Note: some people would add a
schemaLocationhint here; I wouldn’t.)Then change the declaration of
a:footo read:If
a:foocan accept anything, then use anxs:anywildcard in its content model, and you don’t need to import namespaceb(because you’re not referring to anything in it).In the schema document for namespace
bdefine elementbarin the normal way (or attributebar— I think you must have changed your mind on how to present the example).(2) Write a simple top-level ‘driver’ schema document that imports the two namespace-specific schema documents you prepared in step 1. It’s on the
xs:importstatements here that I’d provide the schema location information.Segregating information about physical location of schema documents into a single driver file complicates matters a bit in the short run, by requiring yet another schema document. But it avoids a number of nasty problems that arise when you want to change things just a little bit, later on.