How to check that attributes are unique with RelaxNG?

时光总嘲笑我的痴心妄想 提交于 2019-12-10 13:09:14

问题


With RelaxNG, can I check whether or not the value of an attribute is unique within an enclosing element?

For example, this castle should validate:

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

But this should not (duplicate door in same room):

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

I'm using RelaxNG (compact). I don't know the attribute values 'ahead of time', only that they should be unique within a room.

Thanks!


回答1:


To my knowledge this can't be done in pure RELAX NG. You could use (embedded) Schematron, as we did for the Citation Style Language schema. If you do take this route, note that not all RELAX NG validators parse embedded Schematron, and that support for standalone Schematron schemas is also limited. E.g. the popular Jing XML validator only supports the older Schematron 1.5 version, not the newer ISO Schematron.

For our project, where we use Jing, we use a script to first convert our RELAX NG Compact schema to the RELAX NG XML format (with Trang), then extract the Schematron rules from the RELAX NG XML schema into a standalone Schematron schema (with Saxon and the RNG2Schtrn.xsl XSLT style sheet), and finally validate against the extracted Schematron schema with Jing.

If this hasn't scared you off, I cobbled together the following Schematron 1.5 schema for your problem:

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

When run on the following XML document,

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

Error: Warning: @to values should be unique for a given room.
From line 11, column 5; to line 11, column 21
th"/>↩ <door to="West"/>↩ </r



来源:https://stackoverflow.com/questions/18609355/how-to-check-that-attributes-are-unique-with-relaxng

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!