引言
Relationships由一系列Relationship構成。將Abstract Package看做是一個圖數據結構,則Relationships是圖數據中的邊集合。
?
Package Relationships
對于Package Relationships,其所有引用關系的source對象為Abstract Package,或者看做是Abstract Package的一個虛擬根節點。target為包內的其它part節點,或者外部資源。Package Relationships定義于"/_rel/.rels.xml"文件中。其中首部的“/”表示包根路徑。一個簡單"/_rel/.rels.xml"文件內容實例:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<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文件內容實例:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?><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):"""``<Relationship>`` element, representing a single relationship from asource to a target part."""@staticmethoddef new(rId, reltype, target, target_mode=RTM.INTERNAL):"""Return a new ``<Relationship>`` element."""xml = '<Relationship xmlns="%s"/>' % 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》