Как мне указать числовой диапазон вхождений в RELAX NG? - PullRequest
1 голос
/ 01 сентября 2010

Я разрабатываю схему, используя RELAX NG.Я довольно новичок в этом, поэтому вполне возможно, что я упускаю из виду что-то очевидное, но, похоже, нет удобного способа указать количество вхождений элемента, как вы можете в языке XML-схемы.

Например, предположим, что я хотел указать, что элемент A может содержать от 2 до 5 B элементов.Я не хочу использовать теги zeroOrMore или oneOrMore, потому что у меня действительно есть верхняя граница числа элементов.В XML-схеме я могу использовать свойства minOccurs и maxOccurs для компактного определения этого.Я прочитал официальный учебник по RELAX NG , просмотрел спецификацию и выполнил базовый поиск в Google, но мне не удалось найти какой-либо удобный способ сделать это с RELAXNG.Лучшее, что я могу понять, вам нужно сделать что-то вроде этого:

<element name="A">
  <ref name="B"/>
  <ref name="B"/>
  <optional><ref name="B"/></optional>
  <optional><ref name="B"/></optional>
  <optional><ref name="B"/></optional>
</element>

<define name="B">
  <element name="B">
    <text/>
  </element>
</define>

Это выполнимо, но начнет выглядеть уродливо, когда вам нужно большее количество вхождений.В моей реальной схеме у меня есть один тип элемента, который может встречаться до 256 раз, поэтому необязательные элементы, заданные вручную, будут неуклюжими.Я сделаю это, если понадобится, но я хотел бы знать, есть ли более элегантный способ выражения моих ограничений на вхождения.

1 Ответ

3 голосов
/ 03 сентября 2010

Я действительно боюсь, что в RELAX NG действительно нет ничего страшного.

Я бы выбрал один из двух подходов. Либо создайте шаблоны, либо используйте аннотации Schematron и обрабатывайте их в среде, где вы можете выполнять процессы на обоих языках:

Например, создание групп элементов B:

<define name="B2">
    <ref name="B"/>
    <optional><ref name="B"/></optional>
</define>

<define name="B4">
    <ref name="B2"/>
    <ref name="B2"/>
</define>

позволяя вам медленно создавать группы (в данном случае), один или два элемента, затем 2-4 элемента и так далее. Объединение разных групп позволит вам указать соответствующее количество (в конце концов).

В качестве альтернативы вы можете использовать аннотации Schematron:

<?xml version="1.0" encoding="utf-8"?> 
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
    xmlns:s="http://www.ascc.net/xml/schematron"> 

    <element name="A">
      <s:rule context="A">
        <!-- note - using XPath 2 here -->
        <s:assert test='count(B) lt 6'>A elements may contain no more than 6 B elements</s:assert>
      </s:rule>
      <ref name="B"/>
      <oneOrMore><ref name="B"/></oneOrMore>
    </element>

    <define name="B">
      <element name="B">
        <text/>
      </element>
    </define>

</grammar>

Я предпочитаю последние, так как они упрощают схемы, и их нетрудно смешать, но это зависит от вашей среды проверки.

...