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

Wan*_*uta 7 xml validation xsd relaxng

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

例如,这castle应验证:

<castle>
  <room>
    <door to="North" />
    <door to="South" />
  </room>
  <room>
    <door to="North" />
  </room>
</castle>
Run Code Online (Sandbox Code Playgroud)

但这不应该(重复相同的门room):

<castle>
  <room>
    <door to="Dungeon" />
    <door to="Dungeon" />
  </room>
</castle>
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Rin*_*lle 7

据我所知,这不能在纯RELAX NG中完成.您可以使用(嵌入式)Schematron,就像我们对Citation Style Language架构所做的那样.如果你采取这种方法,请注意并非所有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>
Run Code Online (Sandbox Code Playgroud)

在以下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>
Run Code Online (Sandbox Code Playgroud)

靖会报道

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