GNOME Bugzilla – Bug 303566
Schema validation: wrong evaluation of key/selector/@xpath
Last modified: 2009-08-15 18:40:50 UTC
Please describe the problem: A <key> is declared inside an element declaration. Then the XPath expression given by <selector> is evaluated for the context node *and* the descendants of the context node, not for the context node alone. Example: <Test> <Country code="D"> <City name="Berlin" code="B"> <Part country="D"> <Part country="B"> <!-- Wrong, should be "D" --> </City> </Country> </Test> //Part/@country shall reference @code from the ancestor <Country>. Thus the schema defines a dummy key for country/@code and a keyref to that key: ... <xsd:element name="Country"> ... <xsd:key name="CountryDummyKey"> <xsd:selector xpath="."/> <xsd:field xpath="@code"/> </xsd:key> <xsd:keyref name="..." refer="CountryDummyKey"> <xsd:selector xpath=".//Part"/> <xsd:field xpath="@country"/> </xsd:keyref> </xsd:element> ... Thus schema validation should report an error (message by xerces): [Error] test.xml:12:13: Key 'PartRefCountryDummy' with value 'B' not found for identity constraint of element 'Country'. However, libxml2 (xmllint) applies the selector's xpath expression to Country (the context node) and every descendant inside country. The target nodeset should consist of Country only. But Country/City and Country/City/Part are added. Therefore the example shows four wrong error messages regarding the key that is not valid for Country/City/Part (Part does not have attribute code) and the real validation error is missing, because the Part/@country uses "B" that equals to City/@code, but City/@code is not in the domain of valid key values. Steps to reproduce: XML file "test.xml" <?xml version="1.0" encoding="ISO-8859-1"?> <Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd" > <Country code="D"> <City name="Berlin" code="B"> <Part country="D"/> <Part country="B"/> </City> </Country> <Country code="F"> <City name="Paris" code="P"> <Part country="F"/> <Part country="F"/> </City> </Country> </Test> XML Schema file "test.xsd" <?xml version="1.0" encoding="ISO-8859-1"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:simpleType name="codeType"> <xsd:restriction base="xsd:string"> <xsd:pattern value="[A-Z]+"/> </xsd:restriction> </xsd:simpleType> <xsd:element name="Test"> <xsd:complexType> <xsd:sequence> <xsd:element ref="Country" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Country"> <xsd:complexType> <xsd:sequence> <xsd:element ref="City" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="code" type="codeType" use="required"/> </xsd:complexType> <xsd:key name="CountryDummyKey"> <xsd:selector xpath="."/> <xsd:field xpath="@code"/> </xsd:key> <xsd:keyref name="PartRefCountryDummy" refer="CountryDummyKey"> <xsd:selector xpath=".//Part"/> <xsd:field xpath="@country"/> </xsd:keyref> </xsd:element> <xsd:element name="City"> <xsd:complexType> <xsd:sequence> <xsd:element ref="Part" minOccurs="2" maxOccurs="2"/> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="code" type="xsd:string" use="required"/> </xsd:complexType> </xsd:element> <xsd:element name="Part"> <xsd:complexType> <xsd:attribute name="country" type="codeType" use="required"/> </xsd:complexType> </xsd:element> </xsd:schema> Schema validation: xmllint --noout --schema test.xsd test.xml Actual results: Wrong error messages and the real one is missing: test.xml:9: element Part: Schemas validity error : Element 'Part' [key 'CountryDummyKey']: All 'key' fields must evaluate to a node. test.xml:10: element Part: Schemas validity error : Element 'Part' [key 'CountryDummyKey']: All 'key' fields must evaluate to a node. test.xml:15: element Part: Schemas validity error : Element 'Part' [key 'CountryDummyKey']: All 'key' fields must evaluate to a node. test.xml:16: element Part: Schemas validity error : Element 'Part' [key 'CountryDummyKey']: All 'key' fields must evaluate to a node. test.xml fails to validate Expected results: Expected error message (this one generated by xerces): [Error] test.xml:12:13: Key 'PartRefCountryDummy' with value 'B' not found for identity constraint of element 'Country'. Does this happen every time? Yes. Other information: Excerpt from Schema specification, that rule that is violated: http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/#d0e13819 | 3.11.4 Identity-constraint Definition Validation Rules | Validation Rule: Identity-constraint Satisfied | For an element information item to be locally ·valid· with respect | to an identity-constraint all of the following must be true: | 1 The {selector}, with the element information item as the context node, | evaluates to a node-set (as defined in [XPath]). [Definition:] | Call this the target node set.
Changed the XPath "." to evaluate only one on the first evaluation level for XML Schema IDCs. Fixed in CVS, pattern.c revision 1.22. Thanks for the report!
Added your test case to the regression tests (bug303566_1.xsd and bug303566_1.xml). Thanks again!
This should be closed by release of libxml2-2.6.21, thanks, Daniel