代码之家  ›  专栏  ›  技术社区  ›  ivanacorovic

每个XML的松弛模式和XML模式?

  •  1
  • ivanacorovic  · 技术社区  · 6 年前

    是否有一组XML文档,我们可以为其制定一个RNG,但不能制定一个XML模式(反之亦然)?你能给我举个例子吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Michael Kay    6 年前

    当您谈到“一组XML文档,我们可以为其制定模式”时,您的意思是模式必须接受集合内的所有文档,并拒绝集合外的所有文档吗?一般来说,如果你从一组任意的文档开始,不管你选择了什么样的模式语言,你都不太可能制定出这样的模式。当然,具有这种属性的文档集在不同的模式语言中是不同的。

    此外,如果您的文档集是有限的,那么定义这样的模式并不是非常有用,因为不可能编写任何符合该模式的新文档。如果文档集是无限的,那么定义文档集的唯一真正方法就是编写它们所遵循的模式,这使得整个过程毫无意义。

    有些约束可以在RNG中表达,但不能在XSD中表达,还有一些约束可以在XSD中表达,但不能在RNG中表达。

    例如,RelaxNG可以对混合内容中文本节点的内容定义更精确的规则,而XSD可以对子元素允许的基数范围定义更精确的规则。

    详细的比较取决于您所谈论的XSD版本。

        2
  •  0
  •   C. M. Sperberg-McQueen    5 年前

    正如OP与MK的交流所显示的,这里有一些误解的机会。所以我会在这里给出一个回答,尽管MK实际上已经回答了这个问题。

    我认为问题在于XSD和RNG是否具有相同的表达能力,如果没有,那么其中一个是否比另一个更具表达能力。

    也就是说:每个模式都定义了一组文档(即对该模式有效的文档集)。正如MK所说,有很多文档集,这两种语言都不能定义一个模式,只接受其中的文档集是有效的。因此,也许最清晰的提问方式是:

    给定模式语言L1中的模式,是否保证模式语言L2中的模式接受相同的输入文档集作为有效的?

    或者相当于:

    在L1语言中是否有可以表达的模式,而在L2语言中没有对等的模式?

    答案是,上面提到的每种模式语言都可以表达一些彼此无法表达的模式。

    我会把琐事放在一边,比如 xsi:type RELAXNG使用XSD简单类型的方式可能有一些特殊性,以及我们所说的模式所接受的文档集的确切含义,尽管这些要点在某些上下文中可能很重要。

    没有XSD等价物的松弛模式:

    • 正如MK所指出的,RelaxNG模式可以控制非空白字符数据的位置: (a, b, text, c, d) 在RELAXNG中是一个合法的上下文模型,在XSD中没有等价物。

      因此,在XSD中没有一个等价物的松弛NG模式(紧凑语法)的示例,请考虑以下内容:

      start = e
      e = element e { (e, text, e)? }
      
    • XSD内容模型必须是确定性的(用XSD规范的术语来说,它们必须遵守唯一的粒子属性约束),而RELAXNG内容模型则不必如此。因此,国际象棋游戏中可能的动作序列可以用Relax NG表示,但不能用XSD表示: (white, black)*, white? (因为每一个非确定性FSA都有一个确定性等价物,所以有时让人惊讶的是,对于内容模型来说,情况并非如此:事实的确如此 每个非确定性内容模型都可以重写为等效的确定性内容模型。安妮·布莱格曼·克莱因(Anne Brggemann Klein)在几十年前的研究中发现了一组规则语言,其中没有确定性的内容模型 能力训练 .)

      start = element game { (white, black)*, white? }
      white = element white {sq}
      black = element black {sq}
      sq = attribute square { text }
      
    • 由于Relax NG在内容模型中包含属性,因此在Relax NG中,可以使元素的有效内容模型取决于其属性之一的值,这种方式在XSD 1.1中是可能的,但在XSD 1.0中是不可能的。

      start = element whaddyawant { 
        (attribute gimme { 'a' }, a+) 
        | (attribute gimme { 'b' }, b+)
        }
      a = element a { empty }
      b = element b { empty }
      

    没有松弛等价物的XSD模式:

    • XSD定义类型以支持可在XML DTD中表达的ID/IDREF约束;Relax NG将它们降级为一个单独的“DTD兼容性”,这在实践中(至少在我的经验中)很尴尬且容易出错。特别是,如果模式声明了ID类型的属性,则任何具有通配符属性的通配符元素都可能导致问题。

    • XSD模式可以定义在RELAXNG模式中无法表达的唯一性、键和键引用约束。例子:

      <?xml version="1.0" encoding="UTF-8"?>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified">
        <xs:element name="digraph" type="DG">
          <xs:key name="node-ids">
            <xs:selector xpath="node"/>
            <xs:field xpath="@nodeID"/>
          </xs:key>
          <xs:keyref refer="node-ids" name="arc-ends">
            <xs:selector xpath="node"/>
            <xs:field xpath="@arc-to"/>
          </xs:keyref>
        </xs:element>
        <xs:element name="node" type="N"/>
      
        <xs:complexType name="DG">
          <xs:sequence>
            <xs:element ref="node" minOccurs="0" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
        <xs:complexType name="N">
          <xs:attribute name="nodeID" type="xs:integer"/>
          <xs:attribute name="arc-to" type="xs:integer" use="optional"/>
        </xs:complexType>
      </xs:schema>
      
    • XSD 1.1断言在Relax NG中没有相似性,可以用它们来表达Relax NG中无法表达的约束。例如,每个 district 元素中的值 total/@n 必须等于 n 其他孩子身上的属性( number(total/@n) eq sum((* except total)/@n) ).示例留给读者作为练习。

    请注意,MK说“XSD可以在子元素允许的基数范围上定义更精确的规则”是不对的。我不认为XSD中有任何基数约束不能用RELAXNG表达。诚然,在Relax NG中表示一个约束条件,即发票上必须至少有一行,但不能超过999行,这是相当繁琐的。但这肯定是可能的。内容模型表示必须至少有一个,但不超过九个 a 元素是 (a, a?, a?, a?, a?, a?, a?, a? a?) .我们很容易看到如何扩展它来处理发票上999行的情况。