Как проверить, что атрибуты уникальны с 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 ответ
Насколько мне известно, это не может быть сделано в чистом расслабленном виде. Вы можете использовать (встроенный) 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 (с помощью Saxon и RNG2Schtrn.xsl (таблица стилей XSLT), и, наконец, сверяется с извлеченной схемой Schematron с помощью Jing.
Если вас это не напугало, я собрал следующую схему 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, столбец 21th"/>↩ <door to="West"/>↩ </r