使用 XSD 对元素进行更清晰的扩展 [英] cleaner extension of elements using XSD
问题描述
我定义了 xml 架构,其中包含一个名为field"的元素和一个名为composite-field"的扩展.它的定义如下:
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>
为了在我的 XML 中使用它必须是:
in order to use it in my XML ut has to be:
<field xsi:type="composite-Field">
<value>enjoy</value>
<length>30</length>
</field>
我不希望我的 XML 用户使用架构语法,例如 xsi:type=..." "
因此我的问题是:有没有办法使 XML 的语法成为:
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"/>
然后:
<MyCompositeField>
<value>enjoy</value>
<length>30</length>
</MyCompositeField>
但它也没有通过 XSD 架构验证
but it also didn't pass the XSD schema validation
12/09/2010: 针对建议的答案,我稍微改进了我的问题.
架构如下所示:
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>
所需的 xml 如下所示:
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:无效发现内容以元素MyCompositeField".之一应为{field}".
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>
扩展类型字段"不会修改原始类型.相反,它创建了一个基于旧字段"类型的新类型.如果你想让
和
元素作为
元素的子元素,你应该改变
元素的类型,从field"到composite-Field".
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>
这验证文档
<?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>
其他解决方案是将
元素更改为具有子元素
而不是元素
因为
已经有内容类型composite-Field"
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>
这将验证文档
<?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>
更新 2010-08-14
原海报评论:
但我希望general"元素能够包含field"或composite-field".不要严格要求只有其中一种类型.
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>
和
<?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:
- 如何允许一个元素将这些选择之一作为子元素?"
或者因为您的类型几乎相似: - 如何允许可选元素(可以不存在的元素)?"
如果您最初明确说明您想要实现的目标/代码以及您目前有哪些代码会导致您的问题,那么整个问题本可以更快地解决
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
回答 #1 使用
允许多个独立子内容之一.
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.
回答 #2 如果使用 composite-Field
类型的唯一原因是允许可选的
元素,您可以只需轻松修改原始 field
类型并使用它代替 composite-Field
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>
和
<?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>
这篇关于使用 XSD 对元素进行更清晰的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!