Allowing additional attributes with Relax NG

466 views Asked by At

I am writing a relax NG schema to validate some XML files. For most of the elements, there are some required attributes, and the instances of this XML schema may also add any extra attributes.

For example, here is a valid document :

<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:param="some-uri#params">
   <someElement
        param:requiredAttribute1="foo" 
        param:requiredAttribute2="bar"
        param:freeExtraParam="toto"
        param:freeExtraParam="titi" />
</root>

In my Relax NG schema, I have expressed it this way:

<?xml version="1.0" encoding="utf-8" ?>
<grammar 
    xmlns="http://relaxng.org/ns/structure/1.0" 
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <element name="someElement" >
            <attribute name="requiredAttribute1" />
            <attribute name="requiredAttribute2" />

            <!-- Any extra param --> 
            <zeroOrMore>
                <attribute>
                    <nsName ns="some-uri#params" />
                </attribute>
            </zeroOrMore>
        </element>
    </start>
</grammar>

However, when I try to validate my document with jing, it complains that my schema is not valid :

 error: duplicate attribute "requiredAttribute1" from namespace "some-uri#params"

I guess this is because the requiredAttribute1 also matches the "any attributes" rule. What is the right way for doing this ?

Thanks in advance, Raphael

1

There are 1 answers

2
Vincent Biragnet On

One first point : the start element is the place to define the root elements of the XML. It's not possible to have attribute in this start element.

Concerning your attributes : the following schema, with the use of except should be an answer for you :

<grammar 
    xmlns="http://relaxng.org/ns/structure/1.0" 
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <element name="root">
            <ref name="someElement"/>
        </element>
    </start>
    <define name="someElement">
        <element name="someElement">
            <zeroOrMore>                
                <attribute ns="some-uri#params">
                    <anyName>
                        <except>
                            <name>requiredAttribute1</name>
                            <name>requiredAttribute2</name>
                        </except>
                    </anyName>
                </attribute>
            </zeroOrMore>
            <attribute ns="some-uri#params" name="requiredAttribute1"/>
            <attribute ns="some-uri#params" name="requiredAttribute2"/>
        </element>
    </define>
</grammar>