Ootempl.Relationships (ootempl v0.3.0)
Manages relationship XML for Office Open XML documents.
This module provides functions to parse, modify, and generate relationship IDs
in .docx relationship files (word/_rels/document.xml.rels). Relationships
link the main document to media files, styles, and other resources using unique
IDs like rId1, rId2, etc.
Relationship Structure
Relationship files follow the OpenXML format:
<?xml version="1.0"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.png"/>
</Relationships>Usage
Parse a relationship file:
{:ok, rels} = Relationships.parse_relationships(xml_string)Extract existing IDs:
ids = Relationships.extract_relationship_ids(rels)
# ["rId1", "rId5"]Generate a new unique ID:
new_id = Relationships.generate_unique_id(ids)
# "rId6"Create an image relationship:
rel = Relationships.create_image_relationship(new_id, "media/image2.png")Add the relationship to the XML:
updated_rels = Relationships.add_relationship(rels, rel)Serialize back to XML string:
{:ok, xml_string} = Relationships.serialize_relationships(updated_rels)
Summary
Functions
Adds a relationship to the relationship XML element.
Creates an image relationship entry.
Extracts all relationship IDs from a relationship XML element.
Generates a unique relationship ID given a list of existing IDs.
Parses relationship XML into an :xmerl element structure.
Serializes relationship XML back to an XML string.
Types
Functions
@spec add_relationship(Ootempl.Xml.xml_element(), relationship()) :: Ootempl.Xml.xml_element()
Adds a relationship to the relationship XML element.
Creates a new <Relationship> element and appends it to the <Relationships> root.
Returns the updated XML element with the new relationship added.
Examples
iex> xml = ~s(<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>)
iex> {:ok, rels} = Ootempl.Relationships.parse_relationships(xml)
iex> rel = Ootempl.Relationships.create_image_relationship("rId1", "media/image1.png")
iex> updated = Ootempl.Relationships.add_relationship(rels, rel)
iex> Ootempl.Relationships.extract_relationship_ids(updated)
["rId1"]
@spec create_image_relationship(String.t(), String.t()) :: relationship()
Creates an image relationship entry.
Returns a relationship map with the specified ID and target path. The relationship type is automatically set to the OpenXML image relationship type.
Examples
iex> Ootempl.Relationships.create_image_relationship("rId10", "media/image1.png")
%{
id: "rId10",
type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
target: "media/image1.png"
}
@spec extract_relationship_ids(Ootempl.Xml.xml_element()) :: [String.t()]
Extracts all relationship IDs from a relationship XML element.
Returns a list of relationship ID strings like ["rId1", "rId2", "rId5"].
Examples
iex> xml = ~s(<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://example.com" Target="foo.xml"/></Relationships>)
iex> {:ok, rels} = Ootempl.Relationships.parse_relationships(xml)
iex> Ootempl.Relationships.extract_relationship_ids(rels)
["rId1"]
Generates a unique relationship ID given a list of existing IDs.
Extracts the numeric part from existing IDs (e.g., "rId5" → 5),
finds the maximum, and increments it to generate a new unique ID.
Returns "rId1" if no existing IDs are provided.
Examples
iex> Ootempl.Relationships.generate_unique_id([])
"rId1"
iex> Ootempl.Relationships.generate_unique_id(["rId1", "rId5"])
"rId6"
iex> Ootempl.Relationships.generate_unique_id(["rId1", "rId5", "rId20"])
"rId21"
@spec parse_relationships(String.t()) :: {:ok, Ootempl.Xml.xml_element()} | {:error, term()}
Parses relationship XML into an :xmerl element structure.
Returns {:ok, xml_element} on success, or {:error, reason} if parsing fails.
Examples
iex> xml = ~s(<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>)
iex> {:ok, _rels} = Ootempl.Relationships.parse_relationships(xml)
@spec serialize_relationships(Ootempl.Xml.xml_element()) :: {:ok, String.t()} | {:error, term()}
Serializes relationship XML back to an XML string.
Returns {:ok, xml_string} on success, or {:error, reason} if serialization fails.
Examples
iex> xml = ~s(<?xml version="1.0"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://example.com" Target="foo.xml"/></Relationships>)
iex> {:ok, rels} = Ootempl.Relationships.parse_relationships(xml)
iex> {:ok, serialized} = Ootempl.Relationships.serialize_relationships(rels)
iex> String.contains?(serialized, "rId1")
true