How do you define alternate XML structures in xsd schema? For example the next structures would be optional:
<a>
<b/>
<c>
<d/>
</c>
</a>
and
<a>
<c>
<e/>
</c>
</a>
In the first case there would have to be "b" element if "d" element would be found under "c" element. In the second case there would be NO "b" element allowed if there would be "e" under "c". So I'm looking for sort of this kind of solution:
<xsd:element name="a">
<xsd:complexType>
<xsd:开发者_如何学JAVAall>
(
<xsd:element name="b" type="whatever"/>
<xsd:element name="c">
<xsd:complexType>
<xsd:all>
<xsd:element name="d" type="whatever"/>
</xsd:all>
</xsd:complexType>
</xsd:element> )
) OR (
<xsd:element name="c">
<xsd:complexType>
<xsd:all>
<xsd:element name="e" type="whatever"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
)
</xsd:all>
</xsd:complexType>
</xsd:element>
The reason I wouldn't want to use choice element is because I'm making an editor interface for an XML document and choice would simply look stupid in the editor interface in my case.
The solution to this is you would define two complex types to represent each "state" of your structure. Each complex type would apply different constraints to the nested elements within. Then you can simply group the two complex types as items under an xs:choice
Something like
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="structure">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element name="a1" type="a1" />
<xs:element name="a2" type="a2" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="a1">
<xs:sequence>
<xs:element name="b" type="xs:string" />
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="d" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="a2">
<xs:sequence>
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="e" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
However, you cannot have the same root element name for both complex types.
I'm borrowing the thecolour's answer a bit. What I meant that I didn't want to my choice structure to be inside an element.
With the thecolour's answer a document like this would work:
<?xml version="1.0"?>
<Root>
<structure>
<a1>
<b>jkhgjhg</b>
<c>
<d>asdf</d>
</c>
</a1>
</structure>
</Root>
However the next schema works the way I want (The thecolour's answer has that extra "structure" element, too. I'm skipping that.):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://NS.Schema1" targetNamespace="http://NS.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:sequence>
<xs:element name="b" type="xs:string" />
<xs:element name="c">
<xs:complexType>
<xs:all>
<xs:element name="d" type="xs:string" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:sequence>
<xs:element name="c">
<xs:complexType>
<xs:all>
<xs:element name="e" type="xs:string" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
This has the downside that in the first choice "b" and "c" elements have to be in that order. I don't know why you can't have "all" indicator inside "choice". Possibly because of how the schema parser works internally???
With this schema XML document like this works:
<?xml version="1.0"?>
<Root>
<b>jkhgjhg</b>
<c>
<d>asdf</d>
</c>
</Root>
精彩评论