代码之家  ›  专栏  ›  技术社区  ›  A. Levy

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

  •  1
  • A. Levy  · 技术社区  · 14 年前

    我正在使用RELAXNG开发一个模式。我对这一点还很陌生,所以很可能我忽略了一些显而易见的东西,但是似乎没有一种方便的方法来指定元素的出现次数,就像在xmlschema语言中那样。

    例如,假设我想指定 A B 元素。我不想使用 zeroOrMore oneOrMore 标记,因为我实际上对元素的数量有一个上限。在xmlschema中,我可以使用 minOccurs maxOccurs 属性以紧凑地指定。我通读了这本书 official RELAX NG tutorial ,略过 the spec ,并做了一些基本的谷歌搜索,但我还没有找到任何方便的方式来做这与放松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 回复  |  直到 14 年前
        1
  •  3
  •   Nic Gibson    14 年前

    恐怕真的没有一个非常不笨重的方法来做这件事。

    我会采取两种方法中的一种。构建模式或在可以使用两种语言进行处理的环境中使用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>