XML键约束不适用于使用ref的元素

时间:2013-12-02 08:51:26

标签: xml xpath key xsd xml-validation

所以基本上我遇到的问题是,当我使用元素引用时,我需要的键约束没有得到正确应用。例如,像这样:

<xs:element ref="B" maxOccurs="unbounded"/>

请注意,元素,属性,名称空间等名称只是样本,稍后它们会有逻辑名称

所以有一个如下所示的XML模式:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="test" xmlns="test" elementFormDefault="qualified">  

    <xs:element name="B">
        <xs:complexType>
            <xs:attribute name="c" type="xs:string" use="required"/>
            <xs:attribute name="d" type="xs:hexBinary" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="B" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="A/B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

将应用于以下XML文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<A xmlns="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test schema.xsd">
    <B c="test0" d="0011"/>
    <B c="test1" d="2233"/>
    <B c="test1" d="4455"/>
</A>

正如您所看到的,关键约束基本无效,因为有两个B具有相同的c(在这种情况下为test1)。但是,在根据模式进行验证时(使用visual studio 2012),这不会将其识别为错误。

但是,当我将XML架构更改为此时,它可以正常工作。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="test" xmlns="test" elementFormDefault="qualified">  
    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element name="B" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="c" type="xs:string" use="required"/>
                        <xs:attribute name="d" type="xs:hexBinary" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="A/B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

所以基本上元素包含在没有引用的A中,所以我假设它与键的选择器的xpath属性有关。

问题是,我如何使用元素引用来实现它,因为我希望能够将元素引用用于更复杂的xml结构。

编辑:

所以看起来目标名称空间的解决方案毕竟是正确的,我只需要正确使用它。现在,以下工作表明xml文件无效:

架构:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema targetNamespace="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="test" elementFormDefault="qualified">  

    <xs:element name="B">
        <xs:complexType>
            <xs:attribute name="c" type="xs:string" use="required"/>
            <xs:attribute name="d" type="xs:hexBinary" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="tns:B" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="tns:B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

xml文件也使用了命名空间

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tns:A xmlns:tns="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd">
    <tns:B c="a" d="0011"/>
    <tns:B c="b" d="2233"/>
    <tns:B c="a" d="4455"/>
</tns:A>

1 个答案:

答案 0 :(得分:1)

在指定键和引用的XPath元素时,必须包含目标XML的名称空间。使用示例模式的名称空间tns,密钥定义的XPath表达式必须更改为

<xs:selector xpath="tns:A/tns:B"/>

同样,参考定义的XPath表达式必须更改为

<xs:element ref="tns:B" maxOccurs="unbounded"/>