在RelaxNG中控制属性值顺序

时间:2017-05-17 04:59:37

标签: xsd schema relaxng relaxng-compact

是否可以在Relax NG中控制属性值的顺序?哪个可以使用xs:schema在架构中实现?

XML:

<body>
 <h1 class="title">title</h1>
 <h2 class="subtitle">subtitle</h2>
 <p class="paragraph1">para text 1</p>
 <p class="paragraph2">Para text 2</p>
 <p class="paragraph3">Para text 2</p>
 </body>

类值应该是有序的,第1段应该总是第一个,第2段应该在第1段之后。我在架构中试过的断言:

<xs:assert test="p[1]/@class = 'paragraph1'
and ((every $i in p[2] satisfies $i/@class = 'paragraph2')
and (every $i in p[3] satisfies $i/@class = 'paragraph3'))  "/>

1 个答案:

答案 0 :(得分:1)

一个(紧凑语法)RelaxNG语法来表达问题所描述的内容可以写成:

start = element body { h1?, h2?, p.paragraph1?, p.paragraph2?, p.paragraph3? }
h1 = element h1 { text & attribute class { string } }
h2 = element h2 { text & attribute class { string } }
p.paragraph1 = element p { text & attribute class { string "paragraph1" } }
p.paragraph2 = element p { text & attribute class { string "paragraph2" } }
p.paragraph3 = element p { text & attribute class { string "paragraph3" } }

以RelaxNG XML语法表示:

<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="">
  <start>
    <element name="body">
      <optional>
        <ref name="h1"/>
      </optional>
      <optional>
        <ref name="h2"/>
      </optional>
      <optional>
        <ref name="p.paragraph1"/>
      </optional>
      <optional>
        <ref name="p.paragraph2"/>
      </optional>
      <optional>
        <ref name="p.paragraph3"/>
      </optional>
    </element>
  </start>
  <define name="h1">
    <element name="h1">
      <interleave>
        <text/>
        <attribute name="class">
          <data type="string"/>
        </attribute>
      </interleave>
    </element>
  </define>
  <define name="h2">
    <element name="h2">
      <interleave>
        <text/>
        <attribute name="class">
          <data type="string"/>
        </attribute>
      </interleave>
    </element>
  </define>
  <define name="p.paragraph1">
    <element name="p">
      <interleave>
        <text/>
        <attribute name="class">
          <value type="string">paragraph1</value>
        </attribute>
      </interleave>
    </element>
  </define>
  <define name="p.paragraph2">
    <element name="p">
      <interleave>
        <text/>
        <attribute name="class">
          <value type="string">paragraph2</value>
        </attribute>
      </interleave>
    </element>
  </define>
  <define name="p.paragraph3">
    <element name="p">
      <interleave>
        <text/>
        <attribute name="class">
          <value type="string">paragraph3</value>
        </attribute>
      </interleave>
    </element>
  </define>
</grammar>