I'm trying to figure out how <xs:unique> constraints work, and as part of that, I thought it would be worthwhile to see if I can create some XML that violates an <xs:unique> constraint in its associated schema. So I have this schema in schema.xml:



<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://ift.tt/tphNwY">

<xs:element name="parent">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">

<xs:element name="child">
<xs:complexType>
<xs:attribute name="foo" type="xs:string" />
</xs:complexType>
<xs:unique name="someUniqueConstraint">
<xs:selector xpath="child" />
<xs:field xpath="@foo" />
</xs:unique>
</xs:element>

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

</xs:schema>


And this document in data.xml:



<parent>
<child foo="1" />
<child foo="2" />
<child foo="2" />
</parent>


I'm doing validation with Python's lxml library, which is a binding for libxml2:



from lxml import etree

# load and parse schema and xml
with open('schema.xml', 'r') as f:
schema_root = etree.parse(f)
with open('data.xml', 'r') as f:
data_root = etree.parse(f)

schema = etree.XMLSchema(schema_root)
schema.assertValid(data_root)


My expectation is that the validation code above should raise an exception on the schema.assertValid line, since the uniqueness constraint on the foo attribute of <child> tags is being violated. However, this doesn't happen - the assertion succeeds.


I'm guessing that either 1.) I've written the <xs:unique> constraint incorrectly; or 2.) lxml and/or libxml2 does not actually do uniqueness validation. Either way, what should I do differently to get lxml to enforce a uniqueness constraint such that it does not treat the document above as valid?


(I've managed to get validation errors out of lxml from various other schema violations, so it's not that my install of lxml is broken or anything.)


No comments:

Post a Comment