基于两个键的xsd验证

时间:2014-02-15 20:29:24

标签: xml xsd xmllint

我想验证以下xml:

<?xml version="1.0" encoding="UTF-8"?>

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <root1>
        <items>
            <item id="1">
                <interfaces>
                    <interface id="0"/>
                    <interface id="1"/>
                    <interface id="2"/>
                </interfaces>
            </item>
            <item id="2">
                <interfaces>
                    <interface id="10"/>
                    <interface id="11"/>
                    <interface id="2"/>
                </interfaces>
            </item>
        </items>
        <connections>
            <connection id="1">
                <point item="1" interface="0"/>
                <point item="2" interface="10"/>
            </connection>
            <connection id="2">
                <point item="1" interface="1"/>
                <point item="2" interface="11"/>
            </connection>
            <connection id="3">
                <point item="1" interface="2"/>
                <point item="2" interface="157"/>      <-- this one is not valid as there is no interface 157 under item 2.
            </connection>
        </connections>
    </root1>
</root>

这是验证项目的代码:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="root1" type="root1" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
        <xs:keyref name="endPointIntfKeyRef" refer="interfaceKey">
            <xs:selector xpath="root1/connections/connection/point"/>
            <xs:field xpath="@interface"/>
        </xs:keyref>
    </xs:element>

    <xs:complexType name="root1">
        <xs:sequence>
            <xs:element name="items" minOccurs="1" maxOccurs="1">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="item" type="item" minOccurs="1" maxOccurs="unbounded"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="connections" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="connection" type="connection" minOccurs="1" maxOccurs="unbounded"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="item">
        <xs:sequence>
            <xs:element name="interfaces" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="interface" type="interface" minOccurs="1" maxOccurs="unbounded"/>
                    </xs:sequence>
                </xs:complexType>
                    <xs:unique name="interfaceKey">
                        <xs:selector xpath="interface"/>
                        <xs:field xpath="@id"/>
                    </xs:unique>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="id" type="xs:int" use="required"/>
    </xs:complexType>

    <xs:complexType name="interface">
        <xs:attribute name="id" type="xs:int" use="required"/>
    </xs:complexType>

    <xs:complexType name="connection">
        <xs:sequence>
            <xs:element name="point" minOccurs="2" maxOccurs="2">
                <xs:complexType>
                    <xs:attribute name="item" type="xs:int" use="required"/>
                    <xs:attribute name="interface" type="xs:int" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="id" type="xs:int" use="required"/>
    </xs:complexType>

</xs:schema>

但是它产生了'为键序列发现了多个匹配',我不希望这些匹配在特定项目下是唯一的。

$ xmllint --noout --schema 1.xsd 1.xml 
1.xml:31: Schemas validity error : Element 'point': More than one match found for key-sequence ['2'] of keyref 'endPointIntfKeyRef'.
1.xml:32: Schemas validity error : Element 'point': No match found for key-sequence ['157'] of keyref 'endPointIntfKeyRef'.
1.xml fails to validate

如何只获得第二个错误'元素'点':找不到keyref'endPointIntfKeyRef'的键序列['157']而不是第一个?

1 个答案:

答案 0 :(得分:1)

错误消息是正确的 - interfaceKey中有两个可能匹配的keyref值2。要获得您需要的行为,您需要一个复合键值,包括item ID以及interface ID,然后keyref使用iteminterface point unique上的{1}}属性,但这意味着将<xs:unique name="interfaceKey"> <xs:selector xpath="interface"/> <xs:field xpath="../@id"/><!-- not allowed in 1.0 --> <xs:field xpath="@id"/> </xs:unique> 约束定义为

..

和XML Schema 1.0不允许在字段或选择器(受限制的)XPath表达式中使用{{1}}。