为什么keyref的验证取决于关键元素的排序?

时间:2013-09-16 09:02:04

标签: xsd keyref

我的文档包含带有ID的元素和引用As的B元素,如下所示:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="file:\\\refissue.xsd">

    <A id="x"/>
    <A id="y"/>

    <B><Aref idref="x" /></B>   

</root>

当我验证我的简单架构(见下文)时,我收到以下错误:

cvc-identity-constraint.4.3: Key 'ref' with value 'x' not found for identity constraint of element 'root'.

如果我将A元素的顺序更改为

    <A id="y"/>
    <A id="x"/>

文档验证没有任何错误。


为什么验证结果取决于元素的排序?

这是验证程序或我的架构中的错误吗?


<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>

                <xs:element maxOccurs="unbounded" name="A">
                    <xs:complexType>
                        <xs:attribute name="id" type="xs:ID" />
                    </xs:complexType>
                    <xs:key name="A.KEY">
                        <xs:selector xpath="." />
                        <xs:field xpath="@id" />
                    </xs:key>
                </xs:element>

                <xs:element maxOccurs="unbounded" name="B">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" maxOccurs="1" name="Aref">
                                <xs:complexType>
                                    <xs:attribute name="idref" type="xs:IDREF" />
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>

        <xs:keyref name="ref" refer="A.KEY">
            <xs:selector xpath="B/Aref" />
            <xs:field xpath="@idref" />
        </xs:keyref>

    </xs:element>
</xs:schema>

我尝试使用Eclipse(使用xerces,我认为),xerces-c 3.1.1,xmlstarlet 1.5.0和libxml2 2.7.8进行验证,我只能使用eclipse和xerces获得错误。

2 个答案:

答案 0 :(得分:1)

你是对的,对身份约束的有效性不应该取决于输入中元素的顺序。

在这里,我认为问题在于架构不是很正确,并且Xerces在生成问题的有用诊断方面遇到了麻烦。 (libxml不报告错误的事实只是其不完全覆盖XSD的结果。)

您的键约束应该在元素的范围内定义,其中键值必须是唯一的 - 所以在root元素上,而不是在A元素上。 (根据定义,您的A.KEY约束要求每个A元素的字符串值在该A元素中是唯一的,这将永远是这种情况.id属性被声明为是当然,类型xs:ID确实需要唯一性。类似地,Aref idref属性被声明为xs:IDREF类型的事实意味着你的key和keyref声明实际上并没有在这里做很多工作ID和IDREF尚未完成。)

将A.KEY的声明移动到root元素的声明后,Xerces和Saxon同意模式正常且文档有效。

答案 1 :(得分:0)

我在Eclipse中遇到了类似的问题,直到xs:keyxs:keyref都明确设置为相同的类型。在我的情况下,我同时设置为xs:string(我也使用xs:uniquekeyref unique的引用,但它似乎对{{1}的工作方式相同}和key对)。

因此,例如,如果密钥基于如下所示的元素:

keyref

<xs:complexType name="elementTypeWithKey'> <xs:attribute name="theKey" type="xs:string"/> </xs:complexType> 属性明确theKey,请确保用作keyRef的属性也明确xs:string

xs:string