XML Schema和DTD之间有什么区别?

我在谷歌上搜索过这个问题,但我不清楚什么是XML Schema和DTD(文档类型定义),以及为什么XML Schema比DTD更强大。

如有任何指导,将不胜感激。

216276 次浏览

DTD早于XML,因此本身不是有效的XML.这可能是XSD发明的最大原因。

根据将DTD转换为模式文章的DTD和模式之间的区别部分:

DTD之间

的关键区别 XML模式是XML模式 利用基于XML的语法,而 DTD有一个独特的语法。 来自SGML DTD.尽管DTD是 经常因为这种需要而受到批评 要学习新的语法,语法 本身是相当简洁的。相反的是 对于XML架构为True,这是 详细,但也要利用标记和 XML,这样XML的作者就可以找到 XML Schema Less的语法 恐吓.

DTD的

目标是保持一个级别 与SGML的兼容性 应用程序可能需要 将SGML DTD转换为XML DTD. 然而,为了与其中一个 XML的目标,XML标记的简洁性 是最不重要的,没有 真正关心的是保持语法 简短的.

[...]

那么,当我们转换DTD时,还有哪些其他差异可能特别重要呢?让我们来看一看。

打字

DTD和XML模式之间最显著的区别是能够在模式中结合元素和属性声明创建和使用数据类型。事实上,这是一个非常重要的区别,XML Schema Recommendation的一半内容都是关于数据类型和XML Schema的。我们将在本书的第三部分“ XML模式数据类型”中详细介绍数据类型。

[...]

发生约束

DTD和模式显著不同的另一个方面是出现约束。如果您回忆一下第2章“模式结构”中的前几个示例(或者您自己使用DTD的工作),您可以使用三个符号来限制元素的出现次数:*、+和?。

[...]

枚举

因此,假设我们有一个元素,并且我们希望能够为衬衫定义一个size属性,该属性允许用户选择一个尺寸:小号、中号或大号。我们的DTD将如下所示:

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

[...]

但如果我们想让size成为一个元素呢?我们不能用DTD做到这一点。DTD不提供元素文本内容中的枚举。但是,由于Schema的数据类型,当我们在前面的示例中声明枚举时,我们实际上创建了一个名为__abc2的__abc1,我们现在可以将其与元素一起使用:

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

[...]

DTD非常不受欢迎,因为它作为模式语言的有用性有限,不支持名称空间,也不支持数据类型。此外,DTD的语法相当复杂,很难理解和维护。

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

假设你想拥有

  • person元件
  • 具有名为name的子元素
  • name本身具有firstlast的子元素。

像这样

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

如果同一文档中的city元素也需要具有子元素“ name ”,则DTD要求该“ name ”元素也必须具有firstlast的子元素。尽管city.name不需要firstlast作为孩子。

相反,XML模式允许您在本地声明子元素类型。您可以分别为personcity声明name子元素。从而在这些上下文中为它们提供适当的内容模型。

另一个主要区别是对名称空间的支持。由于DTD是原始XML规范的一部分(并从SGML继承而来),它们根本不能识别名称空间,因为XML名称空间是后来指定的。您可以将DTD与名称空间结合使用,但这需要一些变通,比如必须在DTD中定义前缀并只使用这些前缀,而不是能够使用任意前缀。

对我来说,其他的差异大多是表面的。数据类型支持可以很容易地添加到DTD中,而语法就是语法。(例如,我发现XML模式语法很糟糕,并且永远不想手工维护XML模式,我不会提到DTD或RELAX NG模式;如果我出于某种原因需要一个XML模式,我通常会编写一个RELAX NG模式,并使用trang对其进行转换。

DTD指示XML元素的语法

XML架构是Microsoft用于验证XML的DTD的替代方案

DTD只能有两种类型的数据,即CDATA和PCDATA.但是在模式中,您可以使用编程语言中使用的所有基元数据类型,并且可以灵活地定义自己的自定义数据类型。

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

XML架构定义(XSD)和文档类型定义(DTD)之间的区别包括:

  • XML模式是用XML编写的,而DTD是从SGML语法派生的。
  • XML模式定义了元素和属性的数据类型,而DTD不支持数据类型。
  • XML模式允许支持名称空间,而DTD则不支持。
  • XML模式定义了子元素的数量和顺序,而DTD则没有。
  • 您可以使用XML DOM自己操作XML模式,但在DTD的情况下这是不可能的。
  • 使用XML Schema,用户不需要学习新的语言,但使用DTD对用户来说是困难的。
  • XML模式提供了安全的数据通信,即发送方可以以接收方能够理解的方式描述数据,但在DTD数据的情况下,接收方可能会误解。
  • XML模式是可扩展的,而DTD是不可扩展的。

并不是所有这些要点都是100%准确的,但你得到了要点。

另一方面:

  • DTD允许您定义要在XML文件中使用的新实体值。
  • DTD允许您将其本地扩展到单个XML文件。

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和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的扩展,便于快速学习。

当XML首次出现时,我们被告知它将解决我们所有的问题:XML将是用户友好的,无限可扩展的,避免强类型,并且不需要任何编程技能。我学习了DTD,并编写了自己的XML解析器。15年后,我发现大多数XML都不是用户友好的,也不是非常可扩展的(取决于它的使用)。当一些聪明的木屐将XML连接到数据库时,我就知道数据类型几乎是不可避免的。而且,您应该看到我前几天必须处理的XSLT(转换文件)。如果这不是编程,我不知道什么才是!如今,与XML数据或接口相关的各种问题变坏并不罕见。我喜欢XML,但它已经远远偏离了最初的利他主义出发点。

简短的回答?DTD已被XSD取代,因为XSD允许您更精确地定义XML结构。

相似点

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

  • 首先,它们都声明了一长串元素和属性。
  • 其次,两者都描述了这些元素在XML中如何分组、嵌套或使用。换句话说,它们声明了您允许某人在您的工作流中创建XML文件的规则,
  • 第三,DTD和模式都提供了限制或强制元素的类型或格式的方法。例如,在DTD或架构中,您可以强制将日期字段写为01/05/06或1/5/2006。

不同点:

  • DTD更适合文本密集型应用程序,而模式对于数据密集型工作流有几个优点。

  • 模式是用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>

正如许多人在前面提到那样,XML模式利用基于XML的语法,而DTD具有独特的语法。DTD不支持数据类型,这一点很重要。

让我们看一个非常简单的例子,其中大学有多个学生,每个学生有两个元素“姓名”和“年份”。请注意,我在代码中使用“//-->”只是为了注释。

enter image description here

现在,我将用DTD和XSD编写这个示例。

DTD

<?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>