XSD keyref约束同一元素的多个实例

时间:2016-04-12 12:29:23

标签: xml validation xpath xsd

架构示例 -

<xs:complexType name="EndPointType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1" />
        <xs:element name="Pass" type="SIPMethodType" minOccurs="0" />
        <!-- other elements -->
        <xs:choice>
            <xs:element name="Method" type="MethodType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="MethodName" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
        </xs:choice>
    </xs:choice>
</xs:complexType>

<xs:complexType name="MethodType">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1" />
        <xs:element name="Method" type="SIPMethodType" minOccurs="1" maxOccurs="1" />
        <xs:element name="Response" type="SIPResponseCode" minOccurs="0" maxOccurs="1" />
        <xs:element name="Direction" type="DirectionType" minOccurs="0" maxOccurs="4"/>
    </xs:choice>
</xs:complexType>

<xs:element name="SSME">
    <xs:complexType>
        <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded" >
                <xs:element name="Endpoint" type="EndPointType" minOccurs="1" maxOccurs="unbounded" />
                <xs:element name="Method" type="MethodType" minOccurs="0" maxOccurs="unbounded" />
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="MethodNameKey">
        <xs:selector xpath="./Method"/>
        <xs:field xpath="Name"/>
    </xs:key>
    <xs:keyref name="EpMethodKeyRef"  refer="MethodNameKey">
        <!-- endpoint->methodName (if present) must point at an existing method->name -->
        <xs:selector xpath="./Endpoint"/>
        <xs:field xpath="MethodName"/>
    </xs:keyref>
</xs:element>

有问题的xml -

<Endpoint>
    <Name>ep1</Name>
    <MethodName>method1</MethodName>
    <MethodName>method2</MethodName>
</Endpoint> 

<Method>
    <Name>method1</Name>
    <Method>CANCEL</Method>
    <Direction>Outbound</Direction>
</Method>   

<Method>
    <Name>method2</Name>
    <Method>INVITE</Method>
    <Direction>Inbound</Direction>
</Method>   

xmllint给了我 -  element MethodName:架构有效性错误:元素&#39; MethodName&#39;:XPath&#39; MethodName&#39; keyref身份约束字段&#39; EpMethodKeyRef&#39;计算到具有多个成员的节点集。

如何指定EpMethodKeyRef keyref以允许MethodName的0-n个实例,每个实例必须包含已在MethodNameKey中定义的Method? 我试过了

<xs:field xpath="MethodName[0]"/>
<xs:field xpath="MethodName[1]"/>
<xs:field xpath="MethodName[*]"/>

1 个答案:

答案 0 :(得分:0)

xs:选择器必须选择具有外键引用的每个元素,而xs:field指向每个元素的引用。

MethodName应该移到xs:selector,而xs:field应该有上下文项。代替。这样,每个元素MethodName都将被雾化以获取其值并将其与键进行比较,就像元素Name在键声明中被雾化一样。

    <xs:keyref name="EpMethodKeyRef"  refer="MethodNameKey">
        <!-- endpoint->methodName (if present) must point at an existing method->name -->
        <xs:selector xpath="./Endpoint/MethodName"/>
        <xs:field xpath="."/>
    </xs:keyref>

使用相同选择器的xs:字段的多次使用具有创建元组键的不同语义。