1

我正在使用 RELAX NG 开发模式。我对此很陌生,所以很可能我忽略了一些明显的东西,但似乎没有一种方便的方法来指定一个元素的出现次数,就像在 XML Schema 语言中那样。

例如,假设我想指定一个A元素可能包含 2 - 5 个B元素。我不想使用zeroOrMoreoroneOrMore标记,因为我实际上确实有元素数量的上限。在 XML Schema 中,我可以使用minOccursmaxOccurs属性来紧凑地指定它。我已经阅读了官方的 RELAX NG 教程,浏览了规范,并进行了一些基本的谷歌搜索,但我无法找到任何使用 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 次,因此手动指定的可选元素会很笨重。如果需要,我会这样做,但我想知道是否有更优雅的方式来表达我的出现限制。

4

1 回答 1

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>

我更喜欢后者,因为它使模式更简单,并且将两者混合起来并不难,但这确实取决于您的验证环境。

于 2010-09-03T14:56:50.973 回答