### 什么时候不应该使用 XML(1)

当今计算世界趋向于任何所有正式规范和数据描述都使用 XML。本文作者 － XML 的忠实拥护者 － 提出了一个亵渎神明的问题：“XML 极权主义是个好主意吗？”在这篇观点性文章中，Terence Parr，jGuru 的共同创始人，演示了 XML 形成的糟糕的人机界面。他还提出了一些问题，这些问题是让您自己决定 XML 是否甚至适合于项目的程序对程序接口所需。
记得剪贴前生活的样子吗？（正如我的朋友 Gary Funck 所说，“如果您不是老到记不得的话……那么对您来说很好”）。每个程序以不同方式存储数据，并且很少希望将大量数据送到另一个应用程序，当然肯定不会送到另一个正在运行的程序。在现代操作系统中，粘贴缓冲区以标准方式保持数据，而每个程序觉得合适，就可自由地解释缓冲区数据。例如，可以从数据库程序中剪切一段数据并有意义地粘贴到图形程序中。
类似的，在因特网上的程序之间和机器之间，有一种称之为 XML 的共享数据的标准方式。如果没有 XML 或类似标准，那么两个程序就不可能共享信息 － 出于数据可移植性，用来格式化数据的基本语法必须相同。当然，您可能无法解释这些数据，但至少能将它们读入。看一下如 SOAP 和 XBean 这样的技术，了解 XML 是如何促进互操作性的（请参阅参考资料）。
既然就这个问题我们已经达成了共识，即，XML 是，还是应该是，程序数据互换的公共语言，那么我想反过来讨论一下：什么时候使用 XML 没有意义？首先，需要提醒您的是，XML 看起来象什么以及它与其它数据格式有何不同。如果在这种背景条件下，那么当确定项目数据格式时，我提出一系列可以证明是有用的问题。最后，我将演示我的主要建议：XML 形成了糟糕的人机界面。
您说“date-uh”，我说“dat-uh”
XML 是一种突出数据结构的手段，对于计算机程序，可使它检查该数据更容易。当然，它不是第一种数据格式。古老的逗号分割值（CSV）格式一直使用了几十年来描述成行的数据。例如，这里有可能描述三个日期记录的三行整数：
8, 17, 1964
12, 30, 1975
9, 1, 1970
CSV 在可读性和实现简单性方面很难被击败（想必您必须在第一节计算机课编写程序来读取 CSV 数据）。问题是 CSV 实行严格的数据次序，并且 CSV 不能方便地描述嵌套结构和不同类型的元素。添加花括号以表示嵌套、聚合数据（如 C 和 VRML 中）的做法改善了可表达性，同时使数据具有可读性。例如，要将每行数据与一个标识符相关联，您可能编写：
{{8, 17, 1964}, instructor}
{{12, 30, 1975}, student}
{{9, 1, 1970}, student}
这种格式仍然相当易于进行语法分析，但它继续实行严格的数据次序。解决次序局限性的方法是标记所有数据，譬如：
{date={m=8, d=17, y=1964}, title=instructor}
{date={d=30, m=12, y=1975}, title=student}
{title=student, date={m=9, d=1, y=1970}}
虽然现在数据是位置无关的（您可以看见我已经将一些元素弄混了)，但冗余的标签增加了存储成本并使得更难对它进行语法分析。
当前，我们大多数会按如下以 XML 形式编码数据：
<record>
<date><m>8</m> <d>17</d> <y>1964</y></date> <title>instructor</title>
</record>
<record>
<date><d>30</d> <m>12</m>, <y>1975</y></date> <title>student</title>
</record>
<record>
<title>student</title> <date><m>9</m> <d>1</d> <y>1970</y></date>
</record>
我的观点是有无数的描述格式（语言），带有不同程度的可读性、实现的方便、效率、普遍性和表示方式等等。虽然如此, 我们还是要迅速地集中于完全的 XML 格式的支配。
XML 复杂性和程序间通信
Web 的蓬勃发展和对 HTML 的普遍熟悉把我们领向 XML，它实际只是另一种结构化数据格式。遗憾的是，我们对数据标记得越多，对计算机时间和空间效率的影响就越大。另一方面，数据是任何带 XML 语法分析器的程序都可以读取的标准形式。针对不同情况，需要在简单性和标准化之间解决折衷。当拿不定主意时，也许应该使用 XML。另一个显而易见的规则是，如果您的数据是高度结构化的，那么用 XML。例如，当将 jGuru FAQ 内容（请参阅参考资料 ）导出到我们的伙伴时，提供 XML 数据文件。相反，如果数据不是那么复杂，XML 也许不是最好的选择。通过提一些简单的问题，通常可以为您的程序在 XML 和另一种数据格式之间做出决定。对于本节中四个问题里的任何一个，如果您回答“是”，您可以考虑用更简单的格式来替换标准的 XML 数据。
XML 语法分析器所占比重远远超过了程序的其余部分？
如果编程任务和相关数据相当简单，那么为什么用庞大的 XML 语法分析器以及从结果树中拽出数据所必须的粘接代码，来增添您自己负担呢？请记住，您的目的是完成任务，而不是自己摆弄 DOM 树。程序中组件越多，越容易出现故障。现在，另一方面，如果程序中已经有 XML 语法分析器，那不妨使用它以便在程序中保持一致。
同样回想一下，大多数编程语言对于非 XML 数据格式有小的、内置的语法分析器。例如，Java 有标准方式来读入属性文件，还有易于从简单数据字符串抽出数据的 StreamTokenizer 类。
程序运行在小机器上还是在庞大的数据集上？
如果数据不是高度结构化／嵌套的，并且相对于您的机器是非常巨大的，那么应避免使用 XML，因为您可能需要额外的磁盘和内存存储器。回想 1993 年，我在超级计算中心工作，物理学者经常存储万亿字节的文件（每个文件有 10000 亿字节！）。把 XML 标记添加到数据将使那些文件变得实在太大。我敢说，将整个树放入内存，甚至对于当今的并行超级计算机，也是一项挑战。对 XML 标记进行语法分析的额外处理时间也会达到不可允许的程度。可以肯定，您很少需要模拟高能激光器合成流体动力学，但是甚至如日志这样的普通文件可能也会变得很大。
XML 数据格式阻碍您使用许多如 grep、sed、awk 和 wc 这些基于行的工具了吗？
如果您使用 ls 而非 dir，那么您可能熟悉 Unix 基于行的工具，如 grep 和 wc。我可以确切地说，没有 grep，那么我就是个废人，没有 sed、awk 和 wc，那么我感到十分无助（相信我，那会很糟糕）。按每行一条记录的方式将信息存储成与位置相关的数据，这比标记的 XML 数据有极大的优势，因为可以从命令行或用简单的脚本来对数据执行惊人的转换和操作。我不需要只是为了检查数据而去搭建一个开发环境并编写一个使用 XML 语法分析器。
考虑 jGuru 网站，它生成了许多日志和事务记录。我决定不带标记信息每行写出一条记录 － 行上项的位置决定了它是什么。例如，用这种形式将站点登录事件写入文件：
timestamp: user-id
因为格式是如此简单，我可以用所有 Unix 工具对数据进行操作。如果我想知道在今天用户 1290 已经登录了多少次，可以用如下命令：
$ grep 1290 login.log | wc -l
该命令过滤日志文件以查找任何包含 1290 的行，然后计算结果有多少行数。如果我想要今天所有用户登录的柱状图，可以调用以下命令：
$ awk '{print $2;}' login.log | sort | uniq -c | sort -r -n
不是每个人都这么熟悉 Unix 数据工具，但想说明的是，选择简单的数据格式让我不必借助程序就能够摆弄这些数据。
如果以如下方式使用 XML 记录存储了这些数据：
<login><timestamp>2001-04-06</timestamp><id>1290</id></login>
那么，不编写程序就很难摆弄那些数据。
您的程序是“一次性的”，一个真正唯一的应用程序吗？
您永远不能预测未来程序或数据会发生什么（只要询问一下来自 60 年代的 COBOL 程序员），但偶尔必须编写执行永远不会再出现的任务的程序。例如，如果在升级软件时，正在进一步处理数据库的模式，而该模式转换器可能不会再被用到，这是很正常的（虽然以后可能会借用一些代码）。当将信息从数据库转储以将它重构成新的模式时，您应该为执行速度和易于实现而优化，而不是为与 XML 保持一致。
语法不是语义
最后，就程序间通信而言，我想提醒您，语法不等于语义。数据的语义（含义）完全取决于应用程序。语法分析器只处理语法（格式）。考虑到所有人类语言都用完全相同的数据格式 － 字符串（句子）或声音流（讲话）。但是，如果您曾在巴黎以不说法语者来问路，会知道沟通远比要求同意通过口头表达来交流要困难得多（对于旅行者有用的提示：谈话时多用手比划；这好象有帮助）。