bontade
bontade

Reputation: 3224

XSD - validate that element refers to other elements in XML file

I have this simple XML file:

<TestBuilder>
    <TestBox testValue="x">test1,test2,test2</TestBox>

    <Test id="test1" />
    <Test2 id="test2" />
    <SomethingElse id="test3" />
</TestBuilder>

I would like to write an XSD validation for TestBox to validate that all values (splitted by ,) refer to other element ids in the XML file.

I was able to validate only if the TestBox value is not empty, but I have no idea how to split the values by , and check the references.

<xs:simpleType name="TestBoxType">
    <xs:restriction base="xs:string">
        <xs:minLength value="1"/>
    </xs:restriction>
</xs:simpleType>

<xs:complexType name="TestBoxTagType">
    <xs:simpleContent>
        <xs:extension base="TestBoxType">
            <xs:attribute name="testValue" type="xs:string" use="optional"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

Do you know if it is possible? And how to solve with a generic solution?

Upvotes: 0

Views: 322

Answers (1)

Ghislain Fourny
Ghislain Fourny

Reputation: 7279

XML Schema does support lists, but only space separated, not comma separated (also, note that the document was not well-formed because of a missing / in the end tag for TestBox). That is, what you are asking for should be possible if you can pre-process the document to use spaces instead of commas:

<TestBuilder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="test.xsd">
    <TestBox testValue="x">test1 test2 test2</TestBox>

    <Test id="test1" />
    <Test2 id="test2" />
    <SomethingElse id="test3" />
</TestBuilder>

The above document is valid against the following schema, in which you can see that the type TestBoxTagType extends xs:IDREFS, which is a list of IDREFs. Similarly, all id attributes are defined as having the type xs:ID for the ID mechanism to work.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="TestBuilder">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="TestBox" type="TestBoxTagType"/>
                <xs:element name="Test" type="withIDType"/>
                <xs:element name="Test2" type="withIDType"/>
                <xs:element name="SomethingElse" type="withIDType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="TestBoxTagType">
        <xs:simpleContent>
            <xs:extension base="xs:IDREFS">
                <xs:attribute name="testValue" type="xs:string" use="optional"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="withIDType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="id" type="xs:ID" use="optional"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:schema>

Upvotes: 3

Related Questions