我正在尝试为以下XML构建XSD:
<?xml version="1.0" encoding="UTF-8"?>
<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="people.xsd">
<student>
<name>John</name>
<study_year>4</study_year>
<study_level>A+</study_level>
<age>21</age>
</student>
<tutor>
<name>Thomas</name>
<salary>2300</salary>
<age>45</age>
<expertise>Math</expertise>
</tutor>
<student>
<name>Mike</name>
<study_level>B-</study_level>
<age>20</age>
<study_year>22</study_year>
</student>
</people>
目前我有这个XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="people">
<xs:complexType>
<xs:sequence maxOccurs="1">
<xs:choice maxOccurs="unbounded">
<xs:element maxOccurs="unbounded" minOccurs="1" name="student">
<xs:complexType>
<xs:sequence maxOccurs="1">
<xs:group ref="person"/>
<xs:element name="study_year"/>
<xs:element name="study_level"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" minOccurs="1" name="tutor">
<xs:complexType>
<xs:sequence maxOccurs="1">
<xs:group ref="person"/>
<xs:element name="salary"/>
<xs:element name="expertise"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="person">
<xs:sequence>
<xs:element name="name"/>
<xs:element name="age"/>
</xs:sequence>
</xs:group>
</xs:schema>
这只是我想要制作的XSD的抽象。 我想允许学生和导师中任何元素的顺序。 我还需要xs:group,因为我不想要冗余。
我尝试用xs:all替换xs:sequence,但这不是有效的XSD。
是否可以使用XSD执行此操作?
感谢任何帮助!
答案 0 :(得分:1)
不幸的是,根据规范http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-all
,您只能在element
内all
sequence
我认为没有办法做你想做的事情(以任何顺序排除公共名称和年龄元素,只发生一次)。
例如,这里有两种近似方法:不允许:
两个all
群组中的sequence
个?不,因为all
不能包含all
http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-sequence
以all
进行扩展?不,因为group
只能直接显示在complexType
或all
http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#cos-all-limited内(扩展名不在其中)。虽然从规范中看起来你可以作弊并将choice
放在一个组中并从扩展名中引用 ,但xerces不接受它。
但是可以做出三种不同的权衡来近似它:
(1)。明确列举(例如sequences
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:group name="person">
<xs:choice>
<xs:sequence>
<xs:element name="name"/>
<xs:element name="age"/>
</xs:sequence>
<xs:sequence>
<xs:element name="age"/>
<xs:element name="name"/>
</xs:sequence>
</xs:choice>
</xs:group>
<xs:element name="people">
<xs:complexType>
<xs:sequence maxOccurs="1">
<xs:choice maxOccurs="unbounded">
<xs:element maxOccurs="unbounded" minOccurs="1" name="student">
<xs:complexType>
<xs:sequence>
<xs:group ref="person"/>
<xs:choice>
<xs:sequence>
<xs:element name="study_year"/>
<xs:element name="study_level"/>
</xs:sequence>
<xs:sequence>
<xs:element name="study_level"/>
<xs:element name="study_year"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" minOccurs="1" name="tutor">
<xs:complexType>
<xs:sequence>
<xs:group ref="person"/>
<xs:choice>
<xs:sequence>
<xs:element name="salary"/>
<xs:element name="expertise"/>
</xs:sequence>
<xs:sequence>
<xs:element name="expertise"/>
<xs:element name="salary"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
:{名称,年龄或年龄,名称)的顺序,并有一系列顺序。因为每个组中只有两个元素,所以不会爆炸(至少在此片段中的元素中)。它仍然只是一个近似值,而不是您想要的任何顺序(并且不验证您给出的示例xml):
<xs:choice maxOccurs="unbounded">
<xs:group ref="person"/>
<xs:element name="study_year"/>
<xs:element name="study_level"/>
</xs:choice>
<xs:group name="person">
<xs:choice>
<xs:element name="name"/>
<xs:element name="age"/>
</xs:choice>
</xs:group>
(2)。或者,您可以放弃要求它一次,并使用允许任意数量的选择的旧技巧 - 然后您可以分解选择的一部分:
(1).
(3)。因此,似乎最好放弃保理,并且每次重复使用名称和年龄。 (这听起来你已经不情愿地倾向于)。
我的答案:“不”这是你想要做的明智之举,但我不认为这是可能的。我认为你必须在保理或订购/发生之间做出选择(即在任何地方重复名称/年龄;或者要求订单;或者不限制出现)。
虽然这不是一个明确的答案,但希望通过探索选项,它可以让您了解地形。也许这里一些聪明的人可以建议一个解决方法,允许因子分解,非排序和恰好发生一次(或给出一个明确的证据,证明没有这样的解决办法可能)......?
PS:在任何人编辑之前,我使用{{1}}编号而不是正确的枚举,因为SO格式化程序被它弄糊涂而没有在第二点内拾取xml代码。