Relationships由一系列Relationship构成。将Abstract Package看做是一个图数据结构,则Relationships是图数据中的边集合。
对于Package Relationships,其所有引用关系的source对象为Abstract Package,或者看做是Abstract Package的一个虚拟根节点。target为包内的其它part节点,或者外部资源。Package Relationships定义于"/_rel/.rels.xml"文件中。其中首部的“/”表示包根路径。一个简单"/_rel/.rels.xml"文件内容实例:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail" Target="docProps/thumbnail.emf"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
Relationships>
对于Part Relationships类型。包内part节点可能会引用包内另外的part节点,或者包外资源。对于某一节点,如果其作为source对象,并存在1或者多个Part Relationship类型引用,则会在该节点下创建一个“_rel”目录,并在其中创建一个"_rels.xml"文件。例如,/docProps/core.xml part节点并没有引用其它资源, 则/docProps目录下不存在“rels.xml”文件。而/word/document.xml part节点通常需要引用其它资源,这部分引用信息存储在 word/_rels/document.xml.rels 中。 以下为一个简单的/word/_rels/document.xml.rels文件内容实例:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
<Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/>
Relationships>
注意不论是Package Relationships 或者Part Relationships,source都是唯一的,但target是多样的。
Each set of relationships sharing a common source is represented by a Relationships part.
Relationships以XML 文件格式存储,其根节点元素为复杂类型(complex type) CT_Relationships。根节点下存储的每一子节点元素为 CT_Relationship。CT_Relationship包含四个属性值:
- target mode,该属性为optional,默认取值internal。当target为外部资源时,为external target mode;当target为包内资源时,为internel target mode。
- target, 该属性为required。如果为internel target mode,则target属性值为相对引用信息。
- type, 该属性为required。relationship type 可以以URI形式进行相互比较的。
- id, 该属性为required。为relationship的唯一标识符,在一个Relationships内,rid具有唯一性。
在docx.opc.oxml.CT_Relationship的实例化定义如下:
class CT_Relationship(BaseOxmlElement):
"""
```` element, representing a single relationship from a
source to a target part.
"""
@staticmethod
def new(rId, reltype, target, target_mode=RTM.INTERNAL):
"""
Return a new ```` element.
"""
xml = ' ' % nsmap['pr']
relationship = parse_xml(xml)
relationship.set('Id', rId)
relationship.set('Type', reltype)
relationship.set('Target', target)
if target_mode == RTM.EXTERNAL:
relationship.set('TargetMode', RTM.EXTERNAL)
return relationship
基于Abstract Package Model从docx文档抽取一个Abstract Package,计算程序要做的第一步便是读取“/_rel/.rels.xml” Package Relationships 引用关系文件,从而确定虚拟根节点的直接子节点。然后根据“/[Content_Types].xml”分别处理每个直接子节点的xml文件。在处理子节点part对象时,同样会检查该子节点是否包含Part Relationships,如果包含,则创建一颗子树。不断迭代该过程,并最终将直接子节点与包虚拟根节点连接起来,从而完成Abstract Package抽取。因此创建子节点、加载引用关系是一个“深度优先遍历”过程。
《ISO/IEC 29500-2:Open packaging conventions》