cleaner extension of elements using XSD
I defined xml schema the contains an element called 'field' and an extension to it called 'composite-field'. it is defined as following:
<xs:complexType name="field">
<xs:sequence>
<xs:element name="value" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="composite-Field">
<xs:complexContent>
<xs:extension base="field">
<xs:sequence>
<xs:element name="length" type="xs:integer" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
in order to use it in my XML ut has to be:
<field xsi:type="composite-Field">
<value>enjoy</value>
<length>30</length>
</field>
I don't want my XML users to use schema syntax such as xsi:type=..." "
Therefore my question is: Is there any way to make the syntax of the XML be:<composite-Field>
<value>enjoy</value>
<length>30</length>
</composite-Field>
so the name of the element will imply its inheritence and wouldn't force the users add type attribute ??
I tried this:<xs:element name="MyCompositeField" type="composite-field"/>
and then:
<MyCompositeField>
<value>enjoy</value>
<length>30</length>
</MyCompositeField>
but it also didn't pass the XSD schema validation
12/09/2010: In response the suggested answer I refined my question a liitle bit.
The schema looks like that:<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="general">
<xs:complexType>
<xs:sequence>
<xs:element name="field" type="field" />
</xs:sequence>
</xs:complexType>
</xs:element>
开发者_C百科
<xs:complexType name="field">
<xs:sequence>
<xs:element name="value" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="composite-Field" >
<xs:complexContent>
<xs:extension base="field" >
<xs:sequence>
<xs:element name="length" type="xs:integer" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="MyCompositeField" type="composite-Field"/>
</xs:schema>
and the required xml looks like that:
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
<MyCompositeField>
<value>enjoy</value>
<length>30</length>
</MyCompositeField>
</general>
using this combination I get in response the error message:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'MyCompositeField'. One of '{field}' is expected.
Your question update shows that the real problem is in the <general> element. A valid document would be
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
<field>
<value>enjoy</value>
</field>
</general>
Extending the type "field" does not modify the original type. Instead it creates a new type that is based on the old "field" type. If you wanted to have both <value> and <length> elements as the chlidren of <field> element, you should change the type of the <field> element from "field" to "composite-Field".
<xs:element name="general">
<xs:complexType>
<xs:sequence>
<xs:element name="field" type="composite-Field" />
</xs:sequence>
</xs:complexType>
</xs:element>
This validates document
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
<field>
<value>enjoy</value>
<length>30</length>
</field>
</general>
Other solution would be to change the <general> element have child element <MyCompositeField> instead of element <field> since <MyCompositeField> already has content type "composite-Field"
<xs:element name="general">
<xs:complexType>
<xs:sequence>
<xs:element ref="MyCompositeField" />
</xs:sequence>
</xs:complexType>
</xs:element>
which would validate document
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
<MyCompositeField>
<value>enjoy</value>
<length>30</length>
</MyCompositeField>
</general>
Update 2010-08-14
Comment by original poster:
But I want 'general' element to have the ability to contain either 'field' or 'composite-field'. Not to strict it to have ONLY one of those types.
So is your real problem is that you want your schema to validate both of these documents?
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema2.xsd">
<field>
<value>enjoy</value>
</field>
</general>
and
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema2.xsd">
<MyCompositeField>
<value>enjoy</value>
<length>30</length>
</MyCompositeField>
</general>
In that case the whole question can be seen as:
- "how to allow an element to have one of these choices as a child element?"
or because your types are almost similar: - "how to allow an optional element (element that can be absent)?"
The whole question could have been solved much faster if you had initially clearly stated what is your goal/code that you want to achieve and what code do you currently have that causes your problems
Answer to #1 Use <xs:choice> to allow one of several independent child contents.
With this structure you can allow <general> to have either <field> or <MyCompositeField> child element
<xs:element name="general">
<xs:complexType>
<xs:choice>
<xs:element name="field" type="field" />
<xs:element name="MyCompositeField" type="composite-Field" />
</xs:choice>
</xs:complexType>
</xs:element>
So this change in your schema would allow both of the documents I posted above.
Answer to #2 If the only reason to have type composite-Field is to allow an optional <length> element you could just easily modify the original field type and use it instead of type composite-Field
<xs:complexType name="field">
<xs:sequence>
<xs:element name="value" type="xs:string" />
<xs:element name="length" type="xs:integer" minOccurs="0" />
</xs:sequence>
</xs:complexType>
This schema definition creates a type that allows an optional length element and thus validates both of these documents
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema2.xsd">
<field>
<value>enjoy</value>
</field>
</general>
and
<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema2.xsd">
<field>
<value>enjoy</value>
<length>30</length>
</field>
</general>
加载中,请稍侯......
精彩评论