4

以下命题是否成立:对于每个 DTD,都有一个定义完全相同语言的 XSD,对于每个 XSD,都有一个定义完全相同语言的 DTD。或者换一种说法:任何 DTD 定义的语言集合正是任何 XSD 定义的语言集合?

稍微扩展一下这个问题:XML 文档基本上是一个大字符串。语言是字符串的集合。例如,所有 MathML 文档的(无限)集合是一种语言,所有 RSS 文档的集合也是如此,等等。MathML (RSS, ...) 也是所有 XML 文档的(无限)集合的真子集。您可以使用 DTD 或 XSD 来定义这样的 XML 子集。

现在,每个 DTD 都只定义了一种语言。但是,如果您考虑所有可能的 DTD,就会得到一组语言。我的问题是,这个集合是否与您从所有可能的 XSD 中获得的集合完全相同?如果是这样,那么 DTD 和 XSD 是等价的,因为两者定义的 XML 语言的范围是相等的。

为什么这个问题很重要?如果 DTD 和 XSD 都是等价的,那么就可以编写一个以 DTD 作为输入并为您提供等价 XSD 的程序,而另一个程序则相反。我知道有很多程序声称可以做到这一点,但我怀疑这是否真的可能。

4

2 回答 2

5

一个有趣的问题;问得好!

答案是“不”,在两个方向。

这是一个在 XSD 中没有等效的 DTD:

<!ELEMENT e (#PCDATA | e)* >
<!ENTITY egbdf "Every good boy deserves favor.">

此 DTD 接受的字符序列集包括<e/>and <e>&egbdf;</e>,但不包括<e>&beadgcf;</e>

由于 XSD 验证在所有实体都已扩展的信息集上运行,因此没有 XSD 模式可以区分第三种情况和第二种情况。

DTD 可以表达 XSD 中无法表达的约束的第二个领域涉及 NOTATION 类型。我不会举例;细节太复杂了,我不去查就无法正确记住它们,也不够有趣,让我想这样做。

第三个方面:DTD 以相同的方式处理命名空间属性(也称为命名空间声明)和一般属性;因此,DTD 可以限制名称空间声明在文档中的出现。XSD 架构不能。这同样适用于 xsi 命名空间中的属性。

如果我们忽略所有这些问题,并且仅针对不包含对命名实体的引用而不是预定义实体lt,gt等的字符序列制定问题,那么答案就会改变:对于每个不涉及 NOTATION 声明的 DTD,有是一个 XSD 模式,它在实体扩展后接受完全相同的文档集,并且以忽略命名空间属性和 xsi 命名空间中的属性的方式定义了“相同”。

在另一个方向上,差异领域包括:

  • XSD 是命名空间感知的:以下 XSD 模式接受e指定目标命名空间中的任何元素实例,而不管文档实例中绑定到该命名空间的前缀是什么。

    <xs:schema xmlns:xs="..." targetNamespace="http://example.com/nss/24397">
      <xs:element name="e" type="xs:string"/>
    </xs:schema>
    

    没有 DTD 可以成功地接受所有且仅接受e给定名称空间中的元素。

  • XSD 具有更丰富的数据类型集,可以使用数据类型来约束元素和属性。以下 XSD 架构没有等效的 DTD:

    <xs:schema xmlns:xs="...">
      <xs:element name="e" type="xs:integer"/>
    </xs:schema>
    

    此模式接受 document<e>42</e>但不接受 document <e>42d Street</e>。没有 DTD 可以做出这种区分,因为 DTD 没有限制 #PCDATA 内容的机制。最接近的 DTD 是<!ELEMENT e (#PCDATA)>,它接受两个示例文档。

  • XSD 的xsi:type属性允许对内容模型进行文档内修改。以下架构文档描述的 XSD 架构没有等效的 DTD:

    <xs:schema xmlns:xs="...">
      <xs:complexType name="e">
        <xs:sequence>
          <xs:element ref="e" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="e2">
        <xs:sequence>
          <xs:element ref="e" minOccurs="2" maxOccurs="2"/>
        </xs:sequence>
      </xs:complexType>
    
      <xs:element name="e" type="e"/>
    </xs:schema>
    

    此模式接受文档<e xmlns:xsi="..." xsi:type="e2"><e/><e/></e>并拒绝文档<e xmlns:xsi="..." xsi:type="e2"><e/><e/><e/></e>。DTD 没有使内容模型依赖于文档实例中给定的属性值的机制。

  • XSD 通配符允许在指定元素的子元素中包含任意格式良好的 XML;与 DTD 最接近的方法是使用表单的元素声明<!ELEMENT e ANY>,这是不一样的,因为它需要对所有实际出现的元素进行声明。

  • XSD 1.1 提供了断言和条件类型分配,这在 DTD 中没有类似物。

XSD 的表达能力可能在其他方面超过了 DTD,但我认为这一点已经得到充分说明。

我认为一个公平的总结是:XSD 可以表达 DTD 可以表达的一切,除了实体声明和特殊情况,如命名空间声明和 xsi:* 属性,因为 XSD 被设计成能够这样做。因此,将 DTD 转换为 XSD 模式文档时的信息丢失相对较少,易于理解,并且主要涉及大多数词汇设计者认为没有实质性兴趣的 DTD 人工制品。

XSD 可以表达比 DTD 更多的表达,这也是因为 XSD 就是为此而设计的。在一般情况下,从 XSD 到 DTD 的翻译必然涉及信息丢失(接受的文档集可能需要更大、或更小,或者是重叠集)。关于如何管理信息丢失可以做出不同的选择,这就产生了一个问题:“如何最好地将 XSD 转换为 DTD 形式?” 一定的理论兴趣。(然而,在实践中似乎很少有人觉得这是一个有趣的问题。)

正如您的问题一样,所有这些都集中在作为字符序列的文档、作为文档集的语言以及作为这种意义上的语言生成器的模式语言上。模式中存在的可维护性和信息问题不会变成文档集扩展中的差异(例如,文档模型中的类层次结构的处理)被忽略了。

于 2013-11-02T16:24:22.873 回答
1

没有限定词,答案是否定的。

你必须定义你称之为“语言”的东西。在我看来,您所指的这些语言是用于定义文档模式的语言。模式定义了对文档结构和内容的约束。XSD 可表达的约束远比 DTD 强大。所以不,他们不会是一样的。

DTD 与 XSD 的比较可能有助于您理解为什么不这样做。

于 2013-10-30T15:08:53.140 回答