jaaq
jaaq

Reputation: 1256

XML Validation for config file

I am trying to get an XML Schema for a config file type XML working.

Here's what I have got:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://www.w3schools.com" 
    xmlns="https://www.w3schools.com" elementFormDefault="qualified">

    <xs:element name="config" type="config">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element name="module" maxOccurs="unbounded">
                    <xs:complexType mixed="true">
                        <xs:sequence>
                            <xs:element name="parameter" maxOccurs="unbounded">
                                <xs:complexType mixed="true">
                                    <xs:attribute name="name" type="xs:string" use="required"/>
                                    <xs:attribute name="description" type="xs:string" />
                                    <xs:attribute name="type" type="xs:string" use="required"/>
                                    <xs:attribute name="value" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:attribute name="name" type="xs:string" use="required" />
                        <xs:attribute name="description" type="xs:string" />
                        <xs:attribute name="version" type="xs:string" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Example file that should be legal:

<config>
    <module name="module1">
        <parameter name="param1" value="1.234" type="float"/>
    </module>
    <module name="module2">
        <parameter name="param1" value="Hello there!" type="string"/>
        <parameter name="param2" value="3.1415" type="float"/>
    </module>
</config>

But I get the error Cvc-elt.1.a: Cannot Find The Declaration Of Element config. What did I do wrong here? I have found this answer and at least to me it seems I correctly adopted it for my purpose but somehow my root object config isn't defined.

Upvotes: 2

Views: 344

Answers (1)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22627

There is an error in your XML Schema, since xs:element cannot have both a name and type attribute.

After fixing this: because of how you defined namespaces in your XML Schema, a document that is valid would need to be in the namespace https://www.w3schools.com. The solution is to a) either fix your XML document to include this namespace (see above), or b) change your XSD to not expect a namespace.

Fixing the XML document (no change to the XML Schema)

This would be a valid document:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="https://www.w3schools.com">
    <module name="module1">
        <parameter name="param1" value="1.234" type="float"/>
    </module>
    <module name="module2">
        <parameter name="param1" value="Hello there!" type="string"/>
        <parameter name="param2" value="3.1415" type="float"/>
    </module>
</config>

XML Schema that does not expect a namespace (no change to the XML document)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">

    <xs:element name="config">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element name="module" maxOccurs="unbounded">
                    <xs:complexType mixed="true">
                        <xs:sequence>
                            <xs:element name="parameter" maxOccurs="unbounded">
                                <xs:complexType mixed="true">
                                    <xs:attribute name="name" type="xs:string" use="required"/>
                                    <xs:attribute name="description" type="xs:string" />
                                    <xs:attribute name="type" type="xs:string" use="required"/>
                                    <xs:attribute name="value" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:attribute name="name" type="xs:string" use="required" />
                        <xs:attribute name="description" type="xs:string" />
                        <xs:attribute name="version" type="xs:string" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Other improvements to your XML Schema

Your schema is a bit hard to read, because of the heavy nesting. Here is an alternative version that defines named complex types. Also, your types are "mixed", whereas, looking at your XML document, I do not think they should be.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">

    <xs:element name="config" type="configType" />

    <xs:complexType name="configType">
        <xs:sequence>
            <xs:element name="module" type="moduleType" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="moduleType">
        <xs:sequence>
            <xs:element name="parameter" type="parameterType" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="description" type="xs:string" />
        <xs:attribute name="version" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="parameterType">
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="description" type="xs:string" />
        <xs:attribute name="type" type="xs:string" use="required"/>
        <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>

</xs:schema>

Edit: introducing a different custom namespace

XML Document

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="https://www.myowndomain.com">
    <module name="module1">
        <parameter name="param1" value="1.234" type="float"/>
    </module>
    <module name="module2">
        <parameter name="param1" value="Hello there!" type="string"/>
        <parameter name="param2" value="3.1415" type="float"/>
    </module>
</config>

XML Schema

In the schema, you would remove all references to w3schools.com and replace with your own namespace URI.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="https://www.myowndomain.com" xmlns="https://www.myowndomain.com">

    <xs:element name="config" type="configType" />

    <xs:complexType name="configType">
        <xs:sequence>
            <xs:element name="module" type="moduleType" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="moduleType">
        <xs:sequence>
            <xs:element name="parameter" type="parameterType" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="description" type="xs:string" />
        <xs:attribute name="version" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="parameterType">
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="description" type="xs:string" />
        <xs:attribute name="type" type="xs:string" use="required"/>
        <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>

</xs:schema>

Upvotes: 3

Related Questions