【问题标题】:Validating two different structures with same name验证具有相同名称的两个不同结构
【发布时间】:2019-10-14 12:10:23
【问题描述】:

我有一个元素,比如 Car,它有多个嵌套元素(即 BodyColor 等)。可以有许多不同种类的汽车,但它们都将用元素 Car 表示;但是,BodyColor 中的元素可能不同。

比如我有这两个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?

【问题讨论】:

    标签: xml schema xerces xsd-1.1


    【解决方案1】:

    所以我最终使用 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>
    
    

    这是确保如果 Sunroof 不存在,Gloss 和 Tinted 元素也不存在;同样,如果 Sunroof 存在,则 Hue 元素不存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-09
      相关资源
      最近更新 更多