问题
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>
<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.
回答1:
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>
来源:https://stackoverflow.com/questions/3657714/cleaner-extension-of-elements-using-xsd