引言
前段时间,开源办公软件 LibreOffice 的官方博客发表了一篇颇具话题性的文章:《刻意复杂化的 XML 规范是一种锁定用户的工具》(An artificially complex XML schema as a lock-in tool)。
这篇文章把批判的矛头指向了微软基于 XML 的文件格式——Office Open XML(简称 OOXML)。文章指控,微软虽然表面上开放了 Office 文件格式标准,但通过将其设计得极为复杂,实际上阻碍了与第三方软件的互操作性。文章认为,这种复杂性是刻意为之,与实际需求脱节。这就好比运营一条名义上开放的轨道,却将控制系统设计得只有一家制造商才能运营,从而形成事实垄断。同时,用户往往不加批判地接受这些专有技术,这使得微软能轻易将用户锁定在自己的生态系统中。
为不太熟悉这个话题的朋友补充一些背景。Office 办公软件历史上经历过一次重要的文件格式变化。Office 2003 及更早版本的默认格式(.doc
、.xls
、.ppt
等)是所谓的「二进制格式」,其内容并非人类可直接阅读的文本。从 Office 2007 开始,微软切换到新的默认格式 .docx
、.xlsx
和 .pptx
,其中的 x
就代表 XML。这些新格式的文件本质上是一个 ZIP 压缩包,里面包含了一系列 XML 文件和图片等资源。从 XML 的结构到打包方式,都遵循一套公开的标准,也就是 OOXML。
在微软的推动下,OOXML 先后被国际标准组织采纳为 ECMA-376 和 ISO/IEC 29500。微软也将其纳入所谓「开放规范承诺」,保证不会对实现该标准的行为提出专利权主张。
因此,理论上,任何个人或第三方软件都可以自由地解析、创建和修改 OOXML 文件,实现与 Microsoft Office 的兼容。这听起来很美好,但 LibreOffice 的文章正是对此提出质疑,认为 OOXML 刻意的复杂性使所谓的「开放」变成了一个只进不出的陷阱,是微软维护垄断的工具。
如何看待这种观点?坦白地说,相信没有几个人对 Office 的使用体验印象完美,这也是此文颇具传播力的原因。在我过去的一段法律民工生涯中,跟复杂的 Word 文档斗争是每天的必修课。我还负责编写过一份 Office 教程的 Word 部分,当时的主要思路就是通过介绍 OOXML 格式,来解释 Word 的一些怪癖和相应的最佳实践。因此,我对 Office 和 OOXML 的难用之处也算深有体会。
但即使如此,我并不赞同 LibreOffice 此文的写法和结论:可能是为了大众传播效果,这篇文章情绪、指控过多,而分析、事实太少,实际上错过了一次很好的科普机会。(LibreOffice 后来又发布了一篇更技术性的对比,但仍然直接从代码跳到了结论。)
在我看来,OOXML 格式确实复杂、繁琐、晦涩。但这很可能不是因为微软蓄意阻止第三方兼容,而更多是出于一种不作为的自私心态:在制定标准时,只考虑自身实现的便利,而忽略了一个通用标准应有的质量、简洁和普适。当然,这种不作为客观上也造成了阻碍竞争的结果,但这在动机上与蓄意破坏有别,因此也应受到不同的评价。(具体的法律分析超出了本文的讨论范围。)
为此,本文将基于 OOXML 的语法和制定背景,论证为什么 LibreOffice 的文章指出了正确的问题,却可能得出了错误的结论。
为什么说 OOXML 是一个潦草的标准
LibreOffice 的文章中批评说,「简单如『生存还是毁灭,这是个问题』的句子,都会变成用户无法解读的相互纠缠的标签组合」。我们不妨就以此为例,新建一个 Word 文档,输入
To be or not to be.
(其中 To be 加粗),然后保存,看看都会存储出什么样的结果。
用任意压缩工具解压这个 .docx
文件,从所得的 word/document.xml
文件中就能看到如下内容:
<w:p w14:paraId="6F3ED131" w14:textId="46C90999" w:rsidR="00BF5D1D"
w:rsidRDefault="004249FF">
<w:r w:rsidRPr="00D41C8D">
<w:rPr>
<w:b />
<w:bCs />
</w:rPr>
<w:t>To be</w:t>
</w:r>
<w:r w:rsidRPr="004249FF">
<w:t>, or not to be, that is the question</w:t>
</w:r>
<w:r>
<w:t>.</w:t>
</w:r>
</w:p>
(有节选,额外添加了换行和缩进以便阅读;后同。)
可能你已经晕了……但让我们强打精神来分析一下。这段 XML 的核心结构是一个段落(<w:p>
),它包含了三个「文本块」(run,用 <w:r>
元素来代表)。所谓「文本块」,是指一段具有相同格式的连续文本。在 OOXML 中,每个段落都由一个或多个文本块组成。具体而言——
- 外层
<w:p>
元素代表整个段落。其中的w14:paraId
、w14:textId
和w:rsidR
等属性是 Word 内部用于协同编辑、追踪修订历史的标识符; - 第一个
<w:r>
元素代表加粗的 To be。它包含一个<w:rPr>
(Run Properties) 元素来定义格式。其中,<w:b/>
和<w:bCs/>
分别将西文和中文等复杂书写系统(complex script,尽管这里没有)的字体设置为粗体。之后,<w:t>
元素才包含实际的文本内容; - 第二个
<w:r>
元素包含了后面直到句号前的所有文本。由于这段文本使用默认格式,所以没有<w:rPr>
元素; - 第三个
<w:r>
元素只包含最后的句号,与前面的文本在格式上并无差异。之所以被单独分割出来,仅仅是因为……前面的文字是我粘贴的,而这个句号是我手动输入的。是的,OOXML 就是会因为各种意想不到的原因,给你制造类似的「惊喜」。
作为对比,相同内容若使用 LibreOffice 的 OpenDocument 格式(ODF)存储,其对应的 XML 文件 (content.xml
) 则要好懂得多:
<text:p text:style-name="Standard">
<text:span text:style-name="T1">To be</text:span>
, or not to be, that is the question.
</text:p>
你可能一眼就觉得这是一种更简明的格式。事实上,如果去掉标签和属性开头的命名空间 text:
,它几乎就是一段合法的 HTML。唯一需要解释的是粗体文本的处理方式:ODF 没有用一个「粗体」标签直接包裹 To be,而是创建了一个名为 T1
的自动样式,并将其应用到包裹文本的 <text:span>
元素上。这种做法也体现了 Web 中受推崇的「内容与样式分离」原则。
总的来说,只要你略懂 Web 基础,就能大致看懂 ODF 的 XML。相比之下,OOXML 中那些晦涩的标签名,大概都需要博士后学位才能猜出来是什么意思。
以上分析的还只是最简单的文本格式。如果涉及表格、列表等复杂元素(相信这是每个重度 Word 用户共享的噩梦),OOXML 的复杂程度只会让你更加挠头——几千页的文档不是吃干饭的。
除了形式上的复杂,OOXML 作为一个标准的质量也令人堪忧。在 OOXML 的制定阶段,就有大量文章指出微软提交的规范文档存在诸多技术缺陷,例如——
- 将 Office 中已知的错误或者妥协纳入标准(例如同时保留 1900 或 1904 年为起始点的两套日期系统,并且错误地将 1900 年视为闰年);
- 与语言区域代码(ISO 639)、矢量图形(W3C SVG)、数学符号(W3C MathML)等已确立的现存标准存在冲突;
- 使用定义不明确的计量单位,并且前后矛盾;以及
- 对元素和属性的命名约定(例如大小写规则)既不清晰也不一致。
OOXML 成为 ISO 标准的过程也极富戏剧性。首先,微软选择通过「快速通道」提交标准。这条通道本是为那些技术成熟、业界广泛实施的稳定规范所设。显然,OOXML 在 2006 年被提交时完全不符合这些条件:它是一个全新的规范,唯一的完整实现是尚未正式发布的 Office 2007,其几千页的规范文档更是根本不可能在短时间内完成审阅。谷歌、自由软件基金会欧洲分部(FSFE)等组织和众多技术专家都对此提出了异议。