如何检查RelaxNG的属性是否唯一?

时间:2013-09-04 08:52:08

标签: xml validation xsd relaxng

使用RelaxNG,我可以检查属性的值在封闭元素中是否唯一吗?

例如,此castle应验证:

<castle>
  <room>
    <door to="North" />
    <door to="South" />
  </room>
  <room>
    <door to="North" />
  </room>
</castle>

但这不应该(在同一个room中复制门):

<castle>
  <room>
    <door to="Dungeon" />
    <door to="Dungeon" />
  </room>
</castle>

我正在使用RelaxNG(紧凑型)。我不提前知道属性值,只是在room内它们应该是唯一的。

谢谢!

1 个答案:

答案 0 :(得分:7)

据我所知,这不能在纯RELAX NG中完成。您可以使用(嵌入式)Schematron,就像我们对Citation Style Language schema所做的那样。如果你采取这种方法,请注意并非所有RELAX NG验证器都解析嵌入式Schematron,并且对独立Schematron模式的支持也是有限的。例如。流行的Jing XML验证器仅支持较旧的Schematron 1.5版本,而不支持较新的ISO Schematron。

对于我们使用Jing的项目,我们使用script首先将RELAX NG Compact模式转换为RELAX NG XML格式(使用Trang),然后从中提取Schematron规则。将XML XML模式放入独立的Schematron模式(使用SaxonRNG2Schtrn.xsl XSLT样式表),最后使用Jing验证提取的Schematron模式。

如果这还没有让你害怕,我为你的问题拼凑了以下Schematron 1.5架构:

<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://www.ascc.net/xml/schematron">
  <sch:pattern name="duplicateAttributeValues">
    <sch:rule context="//room/door[@to]">
      <sch:report test="preceding-sibling::door/@to = @to">Warning: @to values should be unique for a given room.</sch:report>
    </sch:rule>
  </sch:pattern>
</sch:schema>

在以下XML文档上运行时,

<?xml version="1.0" encoding="utf-8"?>
<castle>
  <room>
    <door to="North"/>
    <door to="South"/>
    <door to="West"/>
  </room>
  <room>
    <door to="West"/>
    <door to="North"/>
    <door to="West"/>
  </room>
</castle>

Jing will report

  

错误:警告:@to值对于给定的房间应该是唯一的   从第11行第5栏;到第11行,第21列
  th"/>↩ <door to="West"/>↩ </r