0

我的文档包含带有 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 才会出现错误。

4

2 回答 2

1

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

在这里,我认为问题在于模式不太正确,Xerces 无法生成有用的问题诊断。(libxml 不报告错误的事实只是它对 XSD 的不完整覆盖的结果。)

您的键约束应该在键值需要唯一的元素范围内定义——所以在root元素上,而不是在A元素上。(根据定义,您的 A.KEY 约束要求每个A元素的字符串值在该元素中是唯一的,A情况总是如此。将 id 属性声明为类型 xs:ID 的事实确实需要唯一性,当然。同样,将Arefidref 属性声明为 xs:IDREF 类型这一事实意味着您的 key 和 keyref 声明实际上并没有做很多工作,而 ID 和 IDREF 还没有做这些工作。)

一旦将 A.KEY 的声明移到root元素的声明中,Xerces 和 Saxon 就同意架构是好的并且文档是有效的。

于 2013-09-16T19:42:08.727 回答
0

我在 Eclipse 中遇到了类似的问题,直到xs:keyxs:keyref都明确设置为相同的类型。在我的情况下,我将两者都设置为xs:string(我也使用xs:uniquekeyref引用,unique但它似乎对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> 
于 2016-10-25T17:57:00.090 回答