XSD to constrain XML element values to existing XML attribute values? -
the goal constrain best_friend_id have value of existing friend_id attribute in xml:
friends.xml
<?xml version="1.0"?> <friends xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="friends.xsd"> <friend friend_id="1"> <name>john</name> <best_friend_id>2</best_friend_id> </friend> <friend friend_id="2"> <name>kate</name> <best_friend_id>1</best_friend_id> </friend> </friends> e.g. given xml, validation should fail if change value of best_friend_idelement 3.
friends.xsd
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" elementformdefault="qualified" xmlns:vc="http://www.w3.org/2007/xmlschema-versioning"> <xs:complextype name="friendstype"> <xs:sequence> <xs:element ref="friend" maxoccurs="unbounded"/> </xs:sequence> </xs:complextype> <xs:complextype name="friendtype"> <xs:sequence> <xs:element ref="name"/> <xs:element ref="best_friend_id"/> </xs:sequence> <xs:attribute name="friend_id" type="xs:integer"/> </xs:complextype> <xs:element name="friends" type="friendstype"/> <xs:element name="friend" type="friendtype"/> <xs:element name="name" type="xs:string"/> <xs:element name="best_friend_id" type="xs:integer"/> </xs:schema> my idea use power of asserts (xsd 1.1). i've figured out far
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" elementformdefault="qualified" xmlns:vc="http://www.w3.org/2007/xmlschema-versioning" vc:minversion="1.1"> <xs:complextype name="friendstype"> <xs:sequence> <xs:element ref="friend" maxoccurs="unbounded"/> </xs:sequence> </xs:complextype> <xs:complextype name="friendtype"> <xs:sequence> <xs:element ref="name"/> <xs:element ref="best_friend_id"/> </xs:sequence> <xs:attribute name="friend_id" type="xs:integer"/> </xs:complextype> <xs:complextype name="idconstrain"> <xs:simplecontent> <xs:extension base="xs:integer"> <xs:assert test="$value = @friend_id"/> </xs:extension> </xs:simplecontent> </xs:complextype> <xs:element name="friends" type="friendstype"/> <xs:element name="friend" type="friendtype"/> <xs:element name="name" type="xs:string"/> <xs:element name="best_friend_id" type="idconstrain"/> </xs:schema> and validation fails:
severity: error description: cvc-assertion: assertion evaluation ('$value = @friend_id') element 'best_friend_id' on schema type 'idconstrain' did not succeed. start location: 6:10 end location: 6:25 url: http://www.w3.org/tr/xmlschema11-1/#cvc-assertion
i have tried best_friend_id[contains(., @friend_id)] not work well.
you should use following check every best friend id existing friend id. should check bestfriend id not equal itself:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" elementformdefault="qualified" xmlns:vc="http://www.w3.org/2007/xmlschema-versioning" vc:minversion="1.1"> <xs:complextype name="friendstype"> <xs:sequence> <xs:element ref="friend" maxoccurs="unbounded"/> </xs:sequence> <xs:assert test="every $bfid in friend/best_friend_id satisfies $bfid = (friend/@friend_id)"/> <!-- optional check best friend not equals --> <xs:assert test="every $fr in friend satisfies $fr/@friend_id != $fr/best_friend_id"/> </xs:complextype> <xs:complextype name="friendtype"> <xs:sequence> <xs:element ref="name"/> <xs:element ref="best_friend_id"/> </xs:sequence> <xs:attribute name="friend_id" type="xs:integer"/> </xs:complextype> <xs:element name="friends" type="friendstype"/> <xs:element name="friend" type="friendtype"/> <xs:element name="name" type="xs:string"/> <xs:element name="best_friend_id" type="xs:integer"/> </xs:schema> you check bestfriend id diferent friend id inside friend tag instead of friends tag.
<xs:complextype name="friendtype"> <xs:sequence> <xs:element ref="name"/> <xs:element ref="best_friend_id"/> </xs:sequence> <xs:attribute name="friend_id" type="xs:integer"/> <xs:assert test="@friend_id != best_friend_id"/> </xs:complextype>
Comments
Post a Comment