Home > Blockchain >  XML Validation to validate Id defined in Header is used in Body with XSD File
XML Validation to validate Id defined in Header is used in Body with XSD File

Time:10-04

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>
  • Related