如何在 DTD 和 XSD 之间进行选择

Posted

技术标签:

【中文标题】如何在 DTD 和 XSD 之间进行选择【英文标题】:How to choose between DTD and XSD 【发布时间】:2011-01-24 06:56:24 【问题描述】:

我想使用 DTD 或 XSD 来描述我的 XML 文档。我听说 XSD 比 DTD 更好,因为它们支持命名空间和数据类型,而且 DTD 更老。

这是否意味着我应该只使用 XSD 来满足所有未来的需求,而完全忽略 DTD 作为一个选项?我是否应该费心学习 DTD 的结构?

在选择 XSD 和 DTD 时应该考虑哪些因素?

【问题讨论】:

与 vs. 问题的大量重叠:***.com/questions/1544200/… 【参考方案1】:

作为一个单独的练习学习 DTD 可能很重要,只是为了了解它们如何工作以防万一你在其他地方遇到它们,这样你就可以了解 XSD 试图解决的一些问题。

但是,就您当前描述 XML 文档的目的而言,确实坚持使用 XSD。

除了具有更丰富的功能集(如您提到的,包括数据类型和名称空间)之外,它们本身也是 XML 文档,这非常有用。因为它们是 XML,所以您可以更轻松地检查它们的格式正确性和有效性,并且您可以编写像常规 XML 文件一样使用它们的代码(例如,如果您想从模式中自动生成代码类)

【讨论】:

简短而翔实的回答:你的句子让我想知道一些事情:'因为它们是 XML [...]你可以更容易地检查它们的 [有效性]':有趣的是你这样做的方式依赖 DTD 标准 - w3.org/2001/XMLSchema.dtd 我的意思是 XSD 本身是一个有效的 XML 文档,因此您可以在 XmlDocument 或其他任何内容中打开它并解析信息。 DTD 不是有效的 XML,因此如果您想编写读取 DTD 内容的代码(如构建 XML 类的代码生成器),您需要自己解析该格式。我确信有用于读取 DTD 文件的组件/实用程序,但 XSD 为您提供(相对)易于解析的免费 XML。 @monoJohnny - 你说得对,XSD 模式文档有一个 DTD,但说模式文档的验证必然依赖于 DTD 并不完全正确;还有一个用于模式文档的 XSD 模式。提供 DTD 部分是为了引导(当 XSD 的初始草案出来时,DTD 已经得到广泛支持),部分是为了比较目的(帮助精通 DTD 的读者理解架构文档的架构)。【参考方案2】:

这实际上取决于您需要设置的结构有多复杂。

如果您需要命名空间和数据类型之类的东西,一定要使用 XSD。如果您只需要一个快速的小模式来检查,DTD 将为您提供更快的性能,因为不涉及 XML 解析。

据我了解,XSD 是从 DTD 衍生出来的,所以理解 DTD 将为学习 XSD 打下坚实的基础,同时指出 DTD 的一些不足之处。

【讨论】:

【参考方案3】:

理解 DTD 的结构并没有什么坏处(从长远来看,它将帮助您更好地理解 XSD)...但是您应该继续使用 XSD。

【讨论】:

【参考方案4】:

学习DTD没坏处,但一定要使用XSD,因为XSD更有力量,

使用 XSD,您不仅可以验证 XML 标记的结构/层次结构,还可以,

    您可以定义 节点的值。 [日期、数字、字符串等] 您还可以定义自定义 data_types, [例如,对于节点 , 可能的数据可以是 12个月之一..所以你需要 定义一个新的 12 个月 写入所有 12 个月的数据类型 名称作为枚举值.. 如果输入验证显示错误 XML 包含任何其他值 这 12 个值 .. ]​​i> 您可以对 元素的出现,使用 minOccurs 和 maxOccurs,默认值 值为 1 和 1。

.. 还有更多...

有一些限制:就像,

    XSD 文件中定义的元素(名称) 必须仅使用一种数据类型进行定义。 您无法验证节点/属性 使用另一个人的价值 节点/属性。

【讨论】:

>>您无法使用另一个节点/属性的值来验证节点/属性。这是否意味着我不能拥有动态数据类型?例如,用户可以在一个元素中配置一个数据库连接列表,并在不同的元素(比如服务)中使用连接名称,并让 xsd 验证是否存在在服务元素中配置的同名连接? @balki,是的,这是不可能的。您会看到您可以分别验证每个元素及其值。你不能依赖另一个元素。就像您在示例中所说的那样,您无法根据连接元素的值检查服务元素的值。 @balki,但是您可以定义一个枚举列表,以便限制和列出 db_connection 元素的允许值。除了列表中存在的值之外,它不能有任何其他值。对服务等其他元素也可以这样做。 您也可以使用正则表达式 (*, +) 对 DTD 的出现添加限制【参考方案5】:

恕我直言,使用 DTD 有一个非常重要的问题(如果您需要深度验证,可能与 XSD 一起使用):

在 DTD 中,您可以定义自己的实体,例如:

<!ENTITY MyName "DrDr.Hannibal Xerxes Utah,MBA and CEO">

在您的文档中,您可以在任何需要的地方简单地编码 &MyName;而是输入所有这些内容。

进一步假设您有一个类似 XML 的文件(可能由其他应用程序生成),其中包含许多类似的标签但没有根标签,例如:

<?xml version="1.0" encoding="ISO-8859-1"?> <!-- you need this when using foreign characters like 'ü' -->
<Book Author="Author1">
  <Titel>Erstes Buch</Titel>
</Book>
...
<Book Author="Author5">
  <Titel>Fünftes Buch</Titel>
</Book>

假设此文件名为“Booklist.TXT”,

现在你可以编写你的master-xml了:

<?xml version="1.0" encoding="ISO-8859-1"?> <!-- you need this when using foreign characters like 'ü' -->
<DOCTYPE MyRoot [
<ENTITY AllBooks SYSTEM "Booklist.TXT">
]

<MyRoot>
... some prefix-stuff as needed ...
&AllBooks; <!-- here are all the Books -->
... some post stuff es needed ...
</MyBook>

每当您需要在另一个上下文中使用这些书籍时,您只需对周围的 xml 进行编码,并且不要触摸或复制 书单本身,此外,您可以在一个地方对其进行维护,并在任何文档中进行所有更改。

【讨论】:

这是一个很好的观点,但我可能会将“(如果您需要深入验证,可能与 XSD 一起)”更改为“(如果您需要验证,可能与 XSD 一起)”。这是因为您的示例都没有验证 XML。它们只是内部子集中的实体声明。如果需要验证,则还需要使用 XSD,或者需要提供完整的 DTD(外部或内部子集中)。【参考方案6】:

这是一个旧字符串,但万一其他人遇到它...据我所知,DTD 仍然有两个 XSD 没有的好处,即包含 XSD 中不存在的 ENTITY 函数。这是一个非常棒的功能,它告诉编译器如何通过识别要打开哪些程序来处理它们来处理可能不熟悉的文件类型。

此外,DTD 被写入 XML 规范,因此它们可以直接写入 XML 文档,而 XSD 必须作为外部文件存在并连接。没什么大不了的,尤其是在更大的文档中使用时。

我认为 XSD 仍然更好更自然,因为它使用 XML 语法,只是想扮演魔鬼的拥护者:)

【讨论】:

据说Here XSD 文件也可以内联xml 文件,请您解释一下第一个问题吗? (包含ENTITY函数)【参考方案7】:

XML Schema 可以执行更复杂的验证。 例如,如果 DTD 检查 XML 元素的数据类型是整数还是字符串。XML 模式可以执行更复杂的验证,例如 xml 元素是否是以大写字母或正整数开头的字符串。最后,XML 模式使用 XML 语法,是开发 Web 服务的自然选择。

【讨论】:

以上是关于如何在 DTD 和 XSD 之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章

在Eclipse中导入dtd和xsd文件,使XML自动提示 (转)

为啥对 XML 同时使用 XSD 和 DTD?

XML的验证模式DTD与XSD的区别

Maven 中的 XML DTD/Schema 验证

dtd与xsd去区别

Schema 和 DTD 之间的区别