验证两个具有相同名称的不同结构

时间:2019-05-28 23:05:25

标签: xml schema xerces xsd-1.1

我有一个元素,例如 Car ,它具有多个嵌套元素(即 Body Color 等)。可以有许多不同种类的汽车,但是它们都将用元素 Car 表示;但是,正文颜色中的元素可以不同。

例如,我有以下两个xml:

Car1.xml

<Car>
    <Body>
        <Length>2</Length>
        <Shape>Box</Shape>
    </Body>
    <Color>
        <PrimColor>Red</PrimColor>
        <SecColor>
            <Hue>Blue</Hue>
        </SecColor>
    </Color>
</Car>  

Car2.xml

<Car>
    <Body>
        <Length>2</Length>
        <Shape>Box</Shape>
        <Sunroof>True</Sunroof>
    </Body>
    <Color>
        <PrimColor>Red</PrimColor>
        <SecColor>
            <Gloss>True</Gloss>
            <Tinted>False</Tinted>
        </SecColor>
    </Color>
</Car>  

我需要创建一个xsd来验证两个同时满足以下条件的人

  • 如果Body元素不包含元素Sunroof,则元素SecColor只能包含元素Hue,但不需要在其中
  • 如果Body元素包含Sunroof,则元素SecColor只能包含GlossTinted,但不需要在那里(一个,两个或一个都没有)可以出现)

我无法更改xml(已提供给我)。

目前,我只为这些特殊元素设置了minOccurs="0",但这并不强制执行上述规则。

我调查了选择组,但是xerces抱怨“模型组中出现了多个名称为'Body',且类型不同的元素”。这就是我试图做的

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema targetNamespace="Cars" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xs:element name="Car">
        <xs:complexType>
            <xs:sequence>
                <xs:choice>
                    <xs:sequence>
                        <xs:element name="Body">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="Length" type="xs:integer" />
                                    <xs:element name="Shape" type="xs:string" />
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                        <xs:element name="Color">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="PrimColor" type="xs:string" />
                                    <xs:element name="SecColor" >
                                        <xs:complexType>
                                            <xs:sequence>
                                                <xs:element name="Hue" type="xs:string" minOccurs="0" />
                                            </xs:sequence>
                                        </xs:complexType>
                                    </xs:element>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:sequence>
                        <xs:element name="Body">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="Length" type="xs:integer" />
                                    <xs:element name="Shape" type="xs:string" />
                                    <xs:element name="Sunroof" type="xs:boolean" />
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                        <xs:element name="Color">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="PrimColor" type="xs:string" />
                                    <xs:element name="SecColor" >
                                        <xs:complexType>
                                            <xs:sequence>
                                                <xs:element name="Gloss" type="xs:boolean" minOccurs="0" />
                                                <xs:element name="Tinted" type="xs:boolean"  minOccurs="0" />
                                            </xs:sequence>
                                        </xs:complexType>
                                    </xs:element>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我考虑过条件类型,但是它们仅适用于属性,而xml不包含任何条件。

是否可以使用xsd 1.1强制执行这些规则并验证xml?

1 个答案:

答案 0 :(得分:0)

所以我最终使用assert来验证我的xml。

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema targetNamespace="Cars" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <xs:element name="Car">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Body">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Length" type="xs:integer" />
                            <xs:element name="Shape" type="xs:string" />
                            <xs:element name="Sunroof" type="xs:boolean" minOccurs="0"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="Color">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="PrimColor" type="xs:string" />
                            <xs:element name="SecColor" >
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Hue" type="xs:string" minOccurs="0" />
                                        <xs:element name="Gloss" type="xs:boolean" minOccurs="0" />
                                        <xs:element name="Tinted" type="xs:boolean"  minOccurs="0" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:assert test="
                (not(Car/Body/Sunroof) and 
                not(Car/Color/SecColor/Gloss) and
                not(Car/Color/SecColor/Tinted))
                or
                (count(Car/Body/Sunroof) eq 1 and 
                not(Car/Color/SecColor/Hue))" />
        </xs:complexType>
    </xs:element>
</xs:schema>

这可以确保如果天窗不存在,则“光泽度”和“着色”元素也不能;同样,如果存在天窗,则色相元素不能。