Collection object for |_Relationship| instances, having list semantics.
| 11 | |
| 12 | |
| 13 | class Relationships(Dict[str, "_Relationship"]): |
| 14 | """Collection object for |_Relationship| instances, having list semantics.""" |
| 15 | |
| 16 | def __init__(self, baseURI: str): |
| 17 | super(Relationships, self).__init__() |
| 18 | self._baseURI = baseURI |
| 19 | self._target_parts_by_rId: dict[str, Any] = {} |
| 20 | |
| 21 | def add_relationship( |
| 22 | self, reltype: str, target: Part | str, rId: str, is_external: bool = False |
| 23 | ) -> "_Relationship": |
| 24 | """Return a newly added |_Relationship| instance.""" |
| 25 | rel = _Relationship(rId, reltype, target, self._baseURI, is_external) |
| 26 | self[rId] = rel |
| 27 | if not is_external: |
| 28 | self._target_parts_by_rId[rId] = target |
| 29 | return rel |
| 30 | |
| 31 | def get_or_add(self, reltype: str, target_part: Part) -> _Relationship: |
| 32 | """Return relationship of `reltype` to `target_part`, newly added if not already |
| 33 | present in collection.""" |
| 34 | rel = self._get_matching(reltype, target_part) |
| 35 | if rel is None: |
| 36 | rId = self._next_rId |
| 37 | rel = self.add_relationship(reltype, target_part, rId) |
| 38 | return rel |
| 39 | |
| 40 | def get_or_add_ext_rel(self, reltype: str, target_ref: str) -> str: |
| 41 | """Return rId of external relationship of `reltype` to `target_ref`, newly added |
| 42 | if not already present in collection.""" |
| 43 | rel = self._get_matching(reltype, target_ref, is_external=True) |
| 44 | if rel is None: |
| 45 | rId = self._next_rId |
| 46 | rel = self.add_relationship(reltype, target_ref, rId, is_external=True) |
| 47 | return rel.rId |
| 48 | |
| 49 | def part_with_reltype(self, reltype: str) -> Part: |
| 50 | """Return target part of rel with matching `reltype`, raising |KeyError| if not |
| 51 | found and |ValueError| if more than one matching relationship is found.""" |
| 52 | rel = self._get_rel_of_type(reltype) |
| 53 | return rel.target_part |
| 54 | |
| 55 | @property |
| 56 | def related_parts(self): |
| 57 | """Dict mapping rIds to target parts for all the internal relationships in the |
| 58 | collection.""" |
| 59 | return self._target_parts_by_rId |
| 60 | |
| 61 | @property |
| 62 | def xml(self) -> str: |
| 63 | """Serialize this relationship collection into XML suitable for storage as a |
| 64 | .rels file in an OPC package.""" |
| 65 | rels_elm = CT_Relationships.new() |
| 66 | for rel in self.values(): |
| 67 | rels_elm.add_rel(rel.rId, rel.reltype, rel.target_ref, rel.is_external) |
| 68 | return rels_elm.xml |
| 69 | |
| 70 | def _get_matching( |
no outgoing calls
searching dependent graphs…