OPC【2】——Relationships

引言

Relationships由一系列Relationship构成。将Abstract Package看做是一个图数据结构,则Relationships是图数据中的边集合。
 

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 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.

 

.rels.xml文件解析

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》

你可能感兴趣的:(#,Open,Packaging,Conventions,xml)