8

使用 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.

谢谢!

4

1 回答 1

8

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

对于我们使用 Jing 的项目,我们使用脚本首先将 RELAX NG Compact 模式转换为 RELAX NG XML 格式(使用Trang),然后将 Schematron 规则从 RELAX NG 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>

静会报道

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

于 2013-09-04T14:04:36.543 回答