XSD使用组的任何订单

时间:2013-12-04 19:09:46

标签: xml xsd

我正在尝试为以下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执行此操作?

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

不幸的是,根据规范http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-all

,您只能在elementall sequence

我认为没有办法做你想做的事情(以任何顺序排除公共名称和年龄元素,只发生一次)。

例如,这里有两种近似方法:不允许:

但是可以做出三种不同的权衡来近似它:

(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代码。