如何设计一个XSD来限制基于其他元素的元素的使用

时间:2018-07-10 20:16:55

标签: xml xsd

我正在制作一个XSD文件,以验证系统的IO定义不包含任何“不良”配置。

在这种环境下,我有一组不同的硬件板,每个板都有不同数量的输出引脚,其中一些使用额外的硬件进行扩展。

但是,当使用某些硬件扩展时,每块板上的某些引脚将被硬件扩展占用,并且不再在那里正常使用:例如,当我们使用具有MUX II屏蔽的Arduino时,例如引脚17、18 ,而盾牌则使用19。

我要制作我的XSD,以使以下序列有效:

...
<ArduinoDuo name="dev1">
    <pin1 name="bLed1" type="output" voltage="5"/>
    ...
    <pin17 name="bSwitchA" type="output" voltage="5"/>
</ArduinoDuo>

以及

...
<ArduinoDuo name="dev2">
    <pin1 name="bLedXYZ" type="output" voltage="5"/>
    ...
    <pin16 name="bToggleC" type="input" voltage="5"/>
    <MuxII name="LEDExtenderA>
        <pin1 name="bToggleABC" type="input" voltage="25">
    </MuxII>
</ArduinoDuo>

但以下内容无效:

...
<ArduinoDuo name="dev1">
    <pin1 name="bLed1" type="output" voltage="5"/>
    ...
    <pin17 name="bSwitchA" type="output" voltage="5"/>
    <MuxII name="LEDExtenderA>
        <pin1 name="bToggleABC" type="input" voltage="25">
    </MuxII>
</ArduinoDuo>

最终,我希望使用它是可选的,但是当存在声明扩展的Elements时,请限制使用它们。

2 个答案:

答案 0 :(得分:1)

如果只是这种情况,您可以定义一个内容模型

pin1? pin2? ,,,, pin16?, ((pin17?, pin18?, pin19) | MuxII)

使用“,”表示序列“?” (可选)和“ |”供选择。

但是,如果诸如MuxII之类的东西需要缺少某些引脚,那么这将变得不可能,或者无论如何,这将是无望的笨拙。

您需要带有断言的XSD 1.1。然后,您可以编写类似

的内容
<xs:assert test="not(MuxII) or not(pin17 | pin18 | pin19)"/>

表示必须不存在MuxII,或者必须不存在引脚17、18和19。

答案 1 :(得分:1)

这只是XSD架构的草图:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="pininfo">
        <xs:attribute name="name" type="xs:string"/>
        <xs:attribute name="type" type="xs:string"/>
        <xs:attribute name="voltage" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="MuxIIinfo">
        <xs:sequence>
            <xs:element name="pin1" type="pininfo"/>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="ArduinoDuoInfo">
        <xs:sequence>
            <xs:element name="pin1" type="pininfo"/>
            <xs:element name="pin16" type="pininfo"/>
            <xs:choice>
                <xs:sequence>
                    <xs:element name="pin17" type="pininfo" maxOccurs="1" minOccurs="0"/>
                    <xs:element name="pin18" type="pininfo" maxOccurs="1" minOccurs="0"/>
                    <xs:element name="pin19" type="pininfo" maxOccurs="1" minOccurs="0"/>
                </xs:sequence>
                <xs:element name="MuxII" type="MuxIIinfo"/>
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>

    <xs:element name="ArduinoDuo" type="ArduinoDuoInfo"/>

</xs:schema>

有趣的部分是<xs:choice>,它使序列 pin17,pin18,pin19 与标签 MuxII 互斥。请注意,我已经使用minOccursmaxOccurs来使pinXX标签成为可选标签。