【问题标题】:Why does the validation of keyref depend on the ordering of the key element?为什么 keyref 的验证依赖于 key 元素的顺序?
【发布时间】:2016-10-26 01:57:00
【问题描述】:

我的文档包含带有 ID 的 A 元素和引用 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 才会出现错误。

【问题讨论】:

    标签: xsd keyref


    【解决方案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 就同意架构是正确的并且文档是有效的。

    【讨论】:

      【解决方案2】:

      xs:keyxs:keyref 都明确设置为相同类型之前,我在 Eclipse 中遇到了类似的问题。在我的情况下,我将两者都设置为xs:string(我还使用xs:uniquekeyrefunique的引用,但它似乎对keykeyref对的工作方式相同)。

      例如,如果键基于如下所示的元素:

      <xs:complexType name="elementTypeWithKey'>
        <xs:attribute name="theKey" type="xs:string"/>
      </xs:complexType>
      

      并且theKey 属性明确为xs:string,请确保用作keyRef 的属性也明确为xs:string

      <xs:complexType name="elementTypeWithKeyRef">
        <xs:attribute name="theKeyRef" type="xs:string"/>
      </xs:complexType> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多