I have an XML file
<class>
<header>
<Part ID="1"></Part>
<Part ID="2"></Part>
</header>
<body>
<Component_Details>
<Component_Part_No>333</Component_Part_No>
<Part_ID>1</Part_ID>
</Component_Details>
<Component_Details>
<Component_Part_No>444</Component_Part_No>
<Part_ID>3</Part_ID>
</Component_Details>
<Component_Details>
<Component_Part_No>445</Component_Part_No>
<Part_ID>2</Part_ID>
</Component_Details>
</body>
</class>
I want to create an XSD validator to validate that the Part ID's defined in the header are the only numbers used as part ID's in the body. So based on the XML content above only ID 1 and 2 can be used but for Component_Part_No 444 ID of 3 is used so validation should fail.
This Is my XSD
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="class">
<xs:complexType>
<xs:sequence>
<xs:element name="header">
<xs:complexType>
<xs:sequence>
<xs:element name="Part" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:byte" name="ID" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="body">
<xs:complexType>
<xs:sequence>
<xs:element name="Component_Details" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:short" name="Component_Part_No"/>
<xs:element type="xs:byte" name="Part_ID"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Is what I need possible with XSD validation? Without Assertion please as we only use tools that suppport XSD 1.0.
CodePudding user response:
Please try the following XSD.
As @MartinHonnen already pointed out, it could be implemented in XSD 1.0 via xs:key
and xs:keyref
XSD
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="class">
<xs:complexType>
<xs:sequence>
<xs:element name="header">
<xs:complexType>
<xs:sequence>
<xs:element name="Part" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:byte" name="ID" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="body">
<xs:complexType>
<xs:sequence>
<xs:element name="Component_Details" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:short" name="Component_Part_No"/>
<xs:element type="xs:byte" name="Part_ID"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="PartKey">
<xs:selector xpath="./header/Part"/>
<xs:field xpath="@ID"/>
</xs:key>
<xs:keyref name="ComponentKeyRef" refer="PartKey">
<xs:selector xpath="./body/Component_Details"/>
<xs:field xpath="Part_ID"/>
</xs:keyref>
</xs:element>
</xs:schema>