使用Relax NG允许其他属性

时间:2011-11-30 17:49:43

标签: xml xsd relaxng jing

我正在编写一个放松NG模式来验证一些XML文件。 对于大多数元素,有一些必需的属性,这个XML模式的实例也可能添加任何额外的属性。

例如,这是一个有效的文件:

<?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>

在我的Relax NG架构中,我已经这样表达过了:

<?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>

但是,当我尝试使用jing验证我的文档时,它会抱怨我的架构无效:

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

我想这是因为 requiredAttribute1 也匹配“any attributes”规则。 这样做的正确方法是什么?

提前致谢, 圣拉斐尔

1 个答案:

答案 0 :(得分:2)

第一点: start元素是定义XML根元素的地方。在这个start元素中不可能有属性。

关于您的属性:使用except的以下架构应该是您的答案:

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