如何在RELAX NG中指定出现的数值范围?

时间:2010-09-01 13:17:48

标签: xml schema relaxng

我正在使用RELAX NG开发模式。我对此很陌生,所以很有可能我忽略了一些显而易见的事情,但似乎没有一种方便的方法可以在XML Schema语言中指定元素的出现次数。< / p>

例如,假设我想指定A元素可能包含2 - 5个B个元素。我不想使用zeroOrMoreoneOrMore标签,因为实际上我确实有元素数量的上限。在XML Schema中,我可以使用minOccursmaxOccurs属性来紧凑地指定它。我已经阅读official RELAX NG tutorial,浏览了the spec,并做了一些基本的谷歌搜索,但我还没有找到任何方便的方法来使用RELAX NG。我能想到的最好的,你需要做这样的事情:

<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 个答案:

答案 0 :(得分:3)

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

我倾向于选择后者,因为它可以实现更简单的模式,并且不难将两者混合使用,但它确实取决于您的验证环境。