Как проверить уникальность атрибутов с помощью 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.

Спасибо!


person Wander Nauta    schedule 04.09.2013    source источник


Ответы (1)


Насколько мне известно, это невозможно сделать в чистом RELAX NG. Вы можете использовать (встроенный) Schematron, как мы сделали для Citation Схема языка стилей. Если вы выберете этот путь, обратите внимание, что не все валидаторы RELAX NG анализируют встроенный Schematron, и что поддержка автономных схем Schematron также ограничена. Например. популярный Jing XML-валидатор поддерживает только старую версию Schematron 1.5, а не более новую версию ISO Schematron. .

Для нашего проекта, где мы используем Jing, мы используем сценарий, чтобы сначала преобразовать нашу схему RELAX NG Compact в формат RELAX NG XML (с помощью Trang), затем извлеките правила Schematron из XML-схемы RELAX NG в автономную схему Schematron (с Saxon и таблицу стилей XSLT RNG2Schtrn.xsl. ) и, наконец, сверьтесь с извлеченной схемой 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, столбца 21
th"/>↩ <door to="West"/>↩ </r

person Rintze Zelle    schedule 04.09.2013
comment
Спасибо за Ваш ответ! Я посмотрю в Schematron. - person Wander Nauta; 06.09.2013