XML Schema和DTD有什么区别?

202

我已经谷歌了这个问题,但是我不太清楚什么是XML模式和DTD(文档类型定义),以及为什么XML模式比DTD更强大。

非常感谢您的指导。

12个回答

155

来自DTD和Schema之间的区别部分的将DTD转换为Schema文章:

The critical difference between DTDs and XML Schema is that XML Schema utilize an XML-based syntax, whereas DTDs have a unique syntax held over from SGML DTDs. Although DTDs are often criticized because of this need to learn a new syntax, the syntax itself is quite terse. The opposite is true for XML Schema, which are verbose, but also make use of tags and XML so that authors of XML should find the syntax of XML Schema less intimidating.

The goal of DTDs was to retain a level of compatibility with SGML for applications that might want to convert SGML DTDs into XML DTDs. However, in keeping with one of the goals of XML, "terseness in XML markup is of minimal importance," there is no real concern with keeping the syntax brief.

[...]

So what are some of the other differences which might be especially important when we are converting a DTD? Let's take a look.

Typing

The most significant difference between DTDs and XML Schema is the capability to create and use datatypes in Schema in conjunction with element and attribute declarations. In fact, it's such an important difference that one half of the XML Schema Recommendation is devoted to datatyping and XML Schema. We cover datatypes in detail in Part III of this book, "XML Schema Datatypes."

[...]

Occurrence Constraints

Another area where DTDs and Schema differ significantly is with occurrence constraints. If you recall from our previous examples in Chapter 2, "Schema Structure" (or your own work with DTDs), there are three symbols that you can use to limit the number of occurrences of an element: *, + and ?.

[...]

Enumerations

So, let's say we had a element, and we wanted to be able to define a size attribute for the shirt, which allowed users to choose a size: small, medium, or large. Our DTD would look like this:

<!ELEMENT item (shirt)>
<!ELEMENT shirt (#PCDATA)>
<!ATTLIST shirt
    size_value (small | medium | large)>

[...]

But what if we wanted size to be an element? We can't do that with a DTD. DTDs do not provide for enumerations in an element's text content. However, because of datatypes with Schema, when we declared the enumeration in the preceding example, we actually created a simpleType called size_values which we can now use with an element:

<xs:element name="size" type="size_value">

[...]


2
只是一条注释,W3C似乎认为DTD是XML模式语言的一种类型:“有几种不同的模式语言广泛使用,但主要的是文档类型定义(DTD),Relax-NG,Schematron和W3C XSD(XML模式定义)。” http://www.w3.org/standards/xml/schema - Mordechai
1
@Mordechai 我猜他们指定 DTD 作为模式语言而不是 XML 模式。 - kaartic
在“但如果我们希望大小成为一个元素呢?”中: <size name='medium'/> 现在size是一个元素;-) - U. Windl

105
XML Schema Definition (XSD) 和文档类型定义(DTD)之间的差异包括:
  • XML schema使用XML编写,而DTD来源于SGML语法。
  • XML schema为元素和属性定义数据类型,而DTD不支持数据类型。
  • XML schema支持命名空间,而DTD不支持。
  • XML schema定义子元素的数量和顺序,而DTD不会。
  • 可以使用XML DOM来操作XML schema,但在DTD的情况下不可能。
  • 使用XML schema用户无需学习新语言,但使用DTD对用户而言很困难。
  • XML schema提供安全的数据通信,即发件人可以以接收者理解的方式描述数据,但是在DTD的情况下,接收者可能会误解数据。
  • XML schema是可扩展的,而DTD不是可扩展的。
另一方面:
  • DTD允许您为XML文件中使用的新实体值定义新ENTITY值。
  • DTD允许您对单个XML文件进行本地扩展。

1
“使用 XML Schema,用户无需学习新语言,但使用 DTD 对于用户来说很困难。”我认为DTD对人类更易读。 - U. Windl

35

正如许多人先前提到的那样,XML Schema使用基于XML的语法,而DTD具有独特的语法。DTD不支持数据类型,这确实很重要。

让我们看一个非常简单的例子,其中大学有多个学生,每个学生都有两个元素"name"和"year"。请注意,我在我的代码中使用了“// -->”作为注释。

输入图像描述

现在我将同时用DTD和XSD编写此示例。

XSD

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE university[              // --> university as root element 
<!ELEMENT university (student*)>   // --> university has  * = Multiple students
<!ELEMENT student (name,year)>     // --> Student has elements name and year
<!ELEMENT name (#PCDATA)>          // --> name as Parsed character data
<!ELEMENT year (#PCDATA)>          // --> year as Parsed character data
]>

<university>
    <student>
        <name>
            John Niel             //---> I can also use an Integer,not good
        </name>
        <year>
            2000                 //---> I can also use a string,not good
        </year>
    </student>
</university>

XML模式定义语言(XSD)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:complexType name ="uniType">                    //--> complex datatype uniType
 <xsd:sequence>
  <xsd:element ref="student" maxOccurs="unbounded"/> //--> has unbounded no.of students
 </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="stuType">                     //--> complex datatype stuType
 <xsd:sequence>
  <xsd:element ref="name"/>                          //--> has element name
  <xsd:element ref="year"/>                          //--> has element year
 </xsd:sequence>
</xsd:complexType>

<xsd:element name="university" type="uniType"/>       //--> university of type UniType 
<xsd:element name="student" type="stuType"/>          //--> student of type stuType
<xsd:element name="name" type="xsd:string"/>          //--> name of datatype string
<xsd:element name="year" type="xsd:integer"/>         //--> year of datatype integer
</xsd:schema>



<?xml version="1.0" encoding="UTF-8"?>
<university>
    <student>
        <name>
            John Niel          
        </name>
        <year>
            2000                      //--> only an Integer value is allowed
        </year>
    </student>
</university>

1
你应该解释在你的例子中“datatype”实际上有什么作用。 - U. Windl

20

DTD是XML之前的技术,因此本身不是有效的XML。这可能是XSD被发明的最大原因。


准确地说,XSD / XML模式本身就是XML - 这是一件非常好的事情! - marc_s
嗯,XSD除了XML语法外还添加了更多的东西;例如数据类型。 - Rubens Farias
也许可以详细说明为什么DTD是XML格式更加理想。 - U. Windl

10

XSD和DTD之间的相似之处

both specify elements, attributes, nesting, ordering, #occurences

XSD和DTD之间的区别

XSD also has data types, (typed) pointers, namespaces, keys and more.... unlike DTD 

此外,尽管XSD有点啰嗦,但它的语法是XML的扩展,使得学习起来更方便。


3
DTD在#occurences方面比XSD更受限制,只能选择10或10或多个,而XSD可以指定最小和最大数量。 - Jesse Chisholm

9

一个不同之处在于,在DTD中,元素的内容模型完全由其名称确定,而与其在文档中出现的位置无关:

假设您想要有

  • 一个名为person的元素
  • 其中包含名为name的子元素
  • name本身具有子元素firstlast

就像这样

   <person>
       <name>
            <first></first>
            <last></last>
       </name>
   </person>

如果同一文档中的city元素也需要有一个名为“name”的子元素,则DTD要求该“name”元素必须同样具有firstlast作为子元素。尽管city.name不需要将firstlast作为子元素。
相比之下,XML Schema允许您在本地声明子元素类型;您可以分别为personcity声明name子元素。因此,在这些上下文中为它们提供适当的内容模型。
另一个主要区别是对命名空间的支持。由于DTD是原始XML规范的一部分(并继承自SGML),因此它们根本不支持命名空间,因为XML命名空间是稍后指定的。您可以将DTD与命名空间结合使用,但需要进行一些调整,例如被迫在DTD中定义前缀并仅使用这些前缀,而不能使用任意前缀。
对我来说,其他差异大多是表面的。数据类型支持可以轻松添加到DTD中,语法只是语法。(就我个人而言,我发现XML Schema语法很可怕,不会想手动维护XML Schema,但对于DTD或RELAX NG模式,我不会这么说;如果我需要一个XML Schema,我通常会编写一个RELAX NG模式并使用trang进行转换。)

在两个不同的事物(类型)中使用相同的名称“name”从来都不是一个好主意。 - U. Windl

8

相似之处

DTD 和 Schemas 都执行相同的基本功能:

  • 首先,它们都声明了一个元素和属性的列表。
  • 其次,它们都描述了这些元素如何在 XML 中分组、嵌套或使用。换句话说,它们声明了允许某人在工作流程中创建 XML 文件的规则,并且
  • 第三,无论是 DTD 还是 Schema,都提供了限制或强制元素类型或格式的方法。例如,在 DTD 或 Schema 中,你可以强制日期字段的书写方式为 01/05/06 或 1/5/2006。

区别:

  • 对于文本密集型应用程序来说,DTD 更好,而对于数据密集型工作流程,schemas 具有几个优势。
  • Schemas 是用 XML 编写的,因此遵循相同的规则,而 DTD 则是用完全不同的语言编写的。

示例:

DTD:

<?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT employees (Efirstname, Elastname, Etitle, Ephone, Eemail)>
         <!ELEMENT Efirstname (#PCDATA)>
         <!ELEMENT Elastname (#PCDATA)>
         <!ELEMENT Etitle (#PCDATA)>
         <!ELEMENT Ephone (#PCDATA)>
         <!ELEMENT Eemail (#PCDATA)>

XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:od="urn:schemas-microsoft-com:officedata">
<xsd:element name="dataroot">
     <xsd:complexType>
          <xsd:sequence>
               <xsd:element ref="employees" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
          <xsd:attribute name="generated" type="xsd:dateTime"/>
      </xsd:complexType>
</xsd:element>
<xsd:element name="employees">
      <xsd:annotation>
           <xsd:appinfo>
               <od:index index-name="PrimaryKey" index-key="Employeeid " primary="yes"
                unique="yes" clustered="no"/>
          <od:index index-name="Employeeid" index-key="Employeeid " primary="no" unique="no"
           clustered="no"/>
     </xsd:appinfo>
</xsd:annotation>
     <xsd:complexType>
          <xsd:sequence>
               <xsd:element name="Elastname" minOccurs="0" od:jetType="text"
                od:sqlSType="nvarchar">
                    <xsd:simpleType>
                         <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="50"/>
                         </xsd:restriction>
                    </xsd:simpleType>
               </xsd:element>
               <xsd:element name="Etitle" minOccurs="0" od:jetType="text" od:sqlSType="nvarchar">
                    <xsd:simpleType>
                         <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="50"/>
                         </xsd:restriction>
                    </xsd:simpleType>
               </xsd:element>
               <xsd:element name="Ephone" minOccurs="0" od:jetType="text"
                od:sqlSType="nvarchar">
                    <xsd:simpleType>
                         <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="50"/>
                         </xsd:restriction>
                    </xsd:simpleType>
               </xsd:element>
               <xsd:element name="Eemail" minOccurs="0" od:jetType="text"
               od:sqlSType="nvarchar">
                    <xsd:simpleType>
                         <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="50"/>
                         </xsd:restriction>
                    </xsd:simpleType>
               </xsd:element>
               <xsd:element name="Ephoto" minOccurs="0" od:jetType="text"
                od:sqlSType="nvarchar">
                    <xsd:simpleType>
                         <xsd:restriction base="xsd:string">
                              <xsd:maxLength value="50"/>
                         </xsd:restriction>
                    </xsd:simpleType>
               </xsd:element>
          </xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

7

XML DTD

DTD的目的是定义XML文档的结构。它通过列出合法元素来定义结构:

<!ATTLIST contact type CDATA #IMPLIED>
<!ELEMENT address1 ( #PCDATA)>
<!ELEMENT city ( #PCDATA)>
<!ELEMENT state ( #PCDATA)>
<!ELEMENT zip ( #PCDATA)>

XML模式

XML模式可以让模式作者指定元素数量的数据必须是数字或更具体地说,是整数。在以下示例中,我使用了string

<xs:element name="note">
<xs:complexType>
  <xs:sequence>
    <xs:element name="address1" type="xs:string"/>
    <xs:element name="city" type="xs:string"/>
    <xs:element name="state" type="xs:string"/>
    <xs:element name="zip" type="xs:string"/>
  </xs:sequence>
</xs:complexType>


我喜欢你对“结构”的强调;这就像编程语言的语法图表一样:并不是每个语法上正确的程序在语义上都是正确的,而且你不能提供一个语法图表来仅允许语义上正确的程序(似乎这是人们对 XSD 的期望)。 - U. Windl

4
当XML首次推出时,我们被告知它将解决所有问题:XML将是用户友好的,无限可扩展的,避免强类型,并且不需要任何编程技能。我学习了DTD并编写了自己的XML解析器。15年后,我发现大多数XML并不用户友好,也不太可扩展(取决于它的用途)。只要一些聪明人将XML连接到数据库,我就知道数据类型几乎是不可避免的。而且,你应该看看我前几天必须处理的XSLT(转换文件)。如果这不是编程,我不知道什么才是!现在,看到与XML数据或接口有关的各种问题并不罕见。我喜欢XML,但它已经偏离了最初的利他主义起点。
简短的回答是:DTD已被弃用,改用XSD,因为XSD可以更精确地定义XML结构。

我猜超过90%的人只是使用XML来表示具有标准语法的嵌套数据结构,根本不关心DTD。可能是因为使用当前工具从Java对象创建XML非常容易。 - U. Windl

4

DTD只包含两种数据类型,即CDATA和PCDATA。但在模式中,您可以使用编程语言中使用的所有原始数据类型,并且可以灵活定义自己的自定义数据类型。

构建模式的开发人员可以基于核心数据类型以及使用不同的运算符和修饰符创建自定义数据类型。


DTD 也可以有 CDATA 的子集,称为 枚举值 - Jesse Chisholm
请查看我在 https://dev59.com/qnI_5IYBdhLWcg3wEOrq#19912149 上的评论。 - U. Windl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接