4

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

Raphael Jolivet
  • 3,940
  • 5
  • 36
  • 56

1 Answers1

2

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>
Vincent Biragnet
  • 2,950
  • 15
  • 22
  • Thks. For the first point, it was just a mistake I made by simplifying the example for the question. I have edited it and fixed it. I had thought of the "except" keyword, but I wanted to avoid it since it prevents me for writing a generic "extraElements" named pattern. – Raphael Jolivet Dec 01 '11 at 08:57
  • OK. I don't think you can achieve without this without except, and be that generic. – Vincent Biragnet Dec 01 '11 at 09:00