我的文档包含带有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获得错误。
答案 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:key
和xs:keyref
都明确设置为相同的类型。在我的情况下,我同时设置为xs:string
(我也使用xs:unique
和keyref
unique
的引用,但它似乎对{{1}的工作方式相同}和key
对)。
因此,例如,如果密钥基于如下所示的元素:
keyref
且<xs:complexType name="elementTypeWithKey'>
<xs:attribute name="theKey" type="xs:string"/>
</xs:complexType>
属性明确theKey
,请确保用作keyRef的属性也明确xs:string
:
xs:string