Specify an XSD so that the XML element must have the value of another XML element

I'm not sure if this is possible using XML / XSD and they were not lucky to find it.

Is it possible to specify an XSD, so when you write your XML, you can have an element that must reference one of the values ​​contained in another XML element?

For example, if you have this XML:

<car>Audi</car> <car>Ford</car> <car>Honda</car> <person> <drives>Audi</drives> </person> 

How do you define the XSD for drives so that this is one of the values ​​entered for the car?

+4
source share
3 answers

With XSD 1.1, you can use assertions .

Approval components restrict the existence and values ​​of related elements and attributes.

You can use XPath 2.0 expressions to perform validation / validation in a statement.

This sample diagram has a statement for the /doc element, which ensures that the value of /doc/person/drives is equal to one of the /doc/car elements:

 <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.1" elementFormDefault="qualified"> <xs:element name="car" type="xs:string" /> <xs:element name="drives" type="xs:string" /> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element ref="drives"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="doc"> <xs:complexType> <xs:sequence> <xs:element ref="car" maxOccurs="unbounded"/> <xs:element ref="person"/> </xs:sequence> <xs:assert test="person/drives = car"/> </xs:complexType> </xs:element> </xs:schema> 
+4
source

XSD 1.0 will work. Ideally, you should use a combination of the same type of schema and referential integrity.

XSD:

 <?xml version="1.0" encoding="utf-8"?> <!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="sample"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" name="car" type="car"/> <xsd:element name="person"> <xsd:complexType> <xsd:sequence> <xsd:element name="drives" type="car"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:key name="PKCars"> <xsd:selector xpath="car"/> <xsd:field xpath="."/> </xsd:key> <xsd:keyref name="FKPersonCar" refer="PKCars"> <xsd:selector xpath="person/drives"/> <xsd:field xpath="."/> </xsd:keyref> </xsd:element> <xsd:simpleType name="car"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="Audi"/> <xsd:enumeration value="Ford"/> <xsd:enumeration value="Honda"/> </xsd:restriction> </xsd:simpleType> </xsd:schema> 

Diagram:

enter image description here

Invalid XML:

 <sample> <car>Audi</car> <car>Ford</car> <car>Honda</car> <person> <drives>Aud</drives> </person> </sample> 

Error:

 Error occurred while loading [], line 7 position 16 The 'drives' element is invalid - The value 'Aud' is invalid according to its datatype 'car' - The Enumeration constraint failed. specify-xsd-such-that-an-xml-element-must-have-the-value-of-another-xml-element.xml is invalid. 

This error tells you that using an enumerated value makes key / keyref superfluous - you cannot run it.

However, if you cannot have a list of the listed values ​​in your XSD, you should at least provide a minimum length for this type to avoid empty values ​​that create chaos. Of course, although sharing a type is recommended, you don't need to.

Changed XSD:

 <?xml version="1.0" encoding="utf-8"?> <!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="sample"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" name="car" type="car"/> <xsd:element name="person"> <xsd:complexType> <xsd:sequence> <xsd:element name="drives" type="car"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:key name="PKCars"> <xsd:selector xpath="car"/> <xsd:field xpath="."/> </xsd:key> <xsd:keyref name="FKPersonCar" refer="PKCars"> <xsd:selector xpath="person/drives"/> <xsd:field xpath="."/> </xsd:keyref> </xsd:element> <xsd:simpleType name="car"> <xsd:restriction base="xsd:normalizedString"> <xsd:minLength value="1"/> </xsd:restriction> </xsd:simpleType> </xsd:schema> 

Error message:

 Error occurred while loading [], line 9 position 4 The key sequence 'Aud' in Keyref fails to refer to some key. specify-xsd-such-that-an-xml-element-must-have-the-value-of-another-xml-element.xml is invalid. 
+5
source

This is similar to an enumeration, and your example is very similar to the w3schools example.

 <xs:element name="car" type="carType"/> <xs:simpleType name="carType"> <xs:restriction base="xs:string"> <xs:enumeration value="Audi"/> <xs:enumeration value="Golf"/> <xs:enumeration value="BMW"/> </xs:restriction> </xs:simpleType> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="drives" type="carType"/> </xs:sequence> </xs:complexType> </xs:element> 

If you do not want Pangeas to respond.

+1
source

Source: https://habr.com/ru/post/1444968/


All Articles