文/桂浮云,2020年2月12日
参考文献:ECMA 376(第五版)
Office Open XML格式的.docx文档,可以理解为一个Zip压缩包。最小的文档压缩包之中,应当至少包含3部分内容:1.ContentType定义;2.关系定义;3.主文档内容定义。
1. ContentType定义
既然文档是一个压缩包(Package),我们就应该知道其中必然包含了若干被压缩的文件,这些被压缩的文件可以称之为为文档包的片段(part)。
在这些片段(或者说被压缩的文件之中),有一个定义包中其他文件内容类型(ContentType)的文件很关键,物理上,它是存储于文档压缩包(Package)内根目录的[Content_Types].xml的片段文件。
关于[Content_Types].xml的结构分析
既然扩展名是.xml,所以,它是以XML语言编写的,需要通过相关的Xml库进行读写。从文件内容来看,它以Types为根节点,主要包含Default和Override两种子节点。
Default子节点
用于定义默认内容类型,定义了与文件扩展名对应的内容类型。XML格式为<Default Extension="扩展名" ContentType="内容类型" />。注意,这里的扩展名不带英文小数点(.)。
Override子节点
用于定义与具体片段文件对应的内容类型。XML格式为:<Override PartName="片段文件物理存储路径" ContentType="内容类型" />。
最小的[Content_Types].xml文件内容
[Content_Types].xml片段文件内容,必须至少指定两类ContentType。其一,用于指定存储主文档内容的片段文件,其二,用于指定各种包与片段、片段与片段的关系。
用于指定存储主文档内容的片段文件的ContentType
此种ContentType作用比较容易理解,主要是为了通过指定的ContentType,方便查找存储实际文档内容的片段文件。通过ECMA376的示例与实际情况对比来看,有ContentType相同,主文档片段文件物理存储位置不同的情况。
主文档片段的ContentType通常为 application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml,没有发现不同;但在包(Package)中的物理存储路径有位置不同的情况,有的放在了包(Package)的根目录,有的放在了word目录之下。所以建议由ContentType确定主文档片段文件的存放位置。
此种ContentType,通过Override节点获取对应的信息,形式大致如下:
<Override PartName="word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" />
再次提醒,主文档片段文件的PartName可能存在变化,ContentType相同。或参考ECMA-376的相关说明。
用于指定各种包与片段、片段与片段之间关系的ContentType
无论是哪种关系,这种关系同样以包(Package)内片段(part)文件的形式存在,关系文件的扩展名通常为rels。其中,包与片段之间的关系,我们可以称之为包级关系,对于整个docx文件而言,是必须的;片段与片段之间的关系,称之为片段级关系,根据实际需要确定,所以,不一定存在。
根据上面的描述,我们可以猜想到,在实际的文档打包中,并关系文件不唯一。因此,关系文件的ContentType通常由Default子节点定义,或者更应该说,关系文件的扩展名通常由特定的ContentType指定。形式大致如下:
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
不过,包级关系文件的位置是固定的,为/_rels/.rels,实际是以Relations为根节点的XML文件。包级关系文件必须隐含指定包与存储主文档片段文件的关系,以及视需要而存在的与原始数字签名、文件属性片段文件、缩略图等之间的关系。
(续见:文档的关系定义
)