代码之家  ›  专栏  ›  技术社区  ›  13ren

XML模式可以指定共现约束吗?

  •  2
  • 13ren  · 技术社区  · 16 年前

    XML模式文档能否指定两项必须同时出现?

    a b? c d? e      # giving only {ace, abcde}
                     # instead of all combinations: {ace, acde, abce, abcde}
    
    <element name="root">
      <complexType>
        <sequence>
          <element ref="a"/>
          <element ref="b" minOccurs="0"/>
          <element ref="c"/>
          <element ref="d" minOccurs="0"/>
          <element ref="e"/>
        <sequence>
      <complexType>
    <element>
    

    另一个例子:有两个重复的元素,第一个元素出现多少次,第二个元素也出现多少次:

    a b^n c d^n e  # where ^n is a superscript denoting number of repeats
                   # giving {ace, abcde, abbcdde, abbbcddde, ...}
                   # but no other combinations
    
    <element name="root">
      <complexType>
        <sequence>
          <element ref="a"/>
          <element ref="b" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="c"/>
          <element ref="d" minOccurs="0" maxOccurs="unbounded"/>
          <element ref="e"/>
        <sequence>
      <complexType>
    <element>
    

    也许这里面有什么东西 identity constraints 在XMLSchema规范中,这似乎是为了获得一个具有特定特征的实例,而不是确保两个实例具有相同的特征。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Chris Scott    16 年前

    共现是现有1.0模式规范无法解决的问题之一。这是原因之一 Schematron 他被释放了。基于断言的验证可以处理这种情况,以及任何其他可以通过XPath express非常容易地表达的情况。

    此外,在1.1模式中 spec 有断言功能,但我还不知道1.1的处理器广泛支持。

    基于断言的验证通常围绕信用卡交易展开的经典示例,例如:

    <card>
      <number>1111-1111-1111</number>
      <type>mastercard</type>
    </card>
    

    <assert test="starts-with(card/type[.='mastercard'],'1')"/>
    
        2
  •  1
  •   Jan Matt    10 年前

    不确定是否有能力直接做这件事。不过,一个简单的选择是将它们嵌入到单个可选元素中,并要求新元素的每个元素都是必需的。大致如下:

    <element name="root">
      <complexType>
        <sequence>
          <element ref="a"/>
          <element ref="c"/>
          <element ref="f" minOccurs="0">
            <complexType>
              <element ref="b" minOccurs="1"/>
              <element ref="d" minOccurs="1"/>
            </complexType>
          </element>
          <element ref="e"/>
        </sequence>
      </complexType>
    </element>