使用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
内它们应该是唯一的。
谢谢!
答案 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模式(使用Saxon和RNG2Schtrn.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