Skip to content

Commit b3a4b5f

Browse files
author
Steve Canny
committed
add CT_Relationship.new()
1 parent 2221719 commit b3a4b5f

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

opc/oxml.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ class CT_Relationship(OxmlBaseElement):
141141
``<Relationship>`` element, representing a single relationship from a
142142
source to a target part.
143143
"""
144+
@staticmethod
145+
def new(rId, reltype, target, target_mode=RTM.INTERNAL):
146+
"""
147+
Return a new ``<Relationship>`` element.
148+
"""
149+
xml = '<Relationship xmlns="%s"/>' % nsmap['pr']
150+
relationship = oxml_fromstring(xml)
151+
relationship.set('Id', rId)
152+
relationship.set('Type', reltype)
153+
relationship.set('Target', target)
154+
if target_mode == RTM.EXTERNAL:
155+
relationship.set('TargetMode', RTM.EXTERNAL)
156+
objectify.deannotate(relationship, cleanup_namespaces=True)
157+
return relationship
158+
144159
@property
145160
def rId(self):
146161
"""

tests/test_oxml.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""Test suite for opc.oxml module."""
1111

1212
from opc.constants import RELATIONSHIP_TARGET_MODE as RTM
13-
from opc.oxml import CT_Default, CT_Override, CT_Types
13+
from opc.oxml import CT_Default, CT_Override, CT_Relationship, CT_Types
1414

1515
from .unitdata import a_Default, an_Override, a_Relationship, a_Types
1616

@@ -50,6 +50,23 @@ def it_provides_read_access_to_xml_values(self):
5050
assert rel.target_ref == 'docProps/core.xml'
5151
assert rel.target_mode == RTM.INTERNAL
5252

53+
def it_can_construct_from_attribute_values(self):
54+
cases = (
55+
('rId9', 'ReLtYpE', 'foo/bar.xml', None),
56+
('rId9', 'ReLtYpE', 'bar/foo.xml', RTM.INTERNAL),
57+
('rId9', 'ReLtYpE', 'http://some/link', RTM.EXTERNAL),
58+
)
59+
for rId, reltype, target, target_mode in cases:
60+
if target_mode is None:
61+
rel = CT_Relationship.new(rId, reltype, target)
62+
else:
63+
rel = CT_Relationship.new(rId, reltype, target, target_mode)
64+
builder = a_Relationship().with_target(target)
65+
if target_mode == RTM.EXTERNAL:
66+
builder = builder.with_target_mode(RTM.EXTERNAL)
67+
expected_rel_xml = builder.xml
68+
assert rel.xml == expected_rel_xml
69+
5370

5471
class DescribeCT_Types(object):
5572

tests/unitdata.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,34 @@ def __init__(self):
111111
self._reltype = 'ReLtYpE'
112112
self._target = 'docProps/core.xml'
113113
self._target_mode = None
114+
self._indent = 0
114115
self._namespace = ' xmlns="%s"' % NS.OPC_RELATIONSHIPS
115116

117+
def with_rId(self, rId):
118+
"""Set Id attribute to *rId*"""
119+
self._rId = rId
120+
return self
121+
122+
def with_reltype(self, reltype):
123+
"""Set Type attribute to *reltype*"""
124+
self._reltype = reltype
125+
return self
126+
127+
def with_target(self, target):
128+
"""Set XXX attribute to *target*"""
129+
self._target = target
130+
return self
131+
132+
def with_target_mode(self, target_mode):
133+
"""Set TargetMode attribute to *target_mode*"""
134+
self._target_mode = None if target_mode == 'Internal' else target_mode
135+
return self
136+
137+
def without_namespace(self):
138+
"""Don't include an 'xmlns=' attribute"""
139+
self._namespace = ''
140+
return self
141+
116142
@property
117143
def target_mode(self):
118144
if self._target_mode is None:
@@ -122,8 +148,9 @@ def target_mode(self):
122148
@property
123149
def xml(self):
124150
"""Return Relationship element"""
125-
tmpl = '<Relationship%s Id="%s" Type="%s" Target="%s"%s/>\n'
126-
return tmpl % (self._namespace, self._rId, self._reltype,
151+
tmpl = '%s<Relationship%s Id="%s" Type="%s" Target="%s"%s/>\n'
152+
indent = ' ' * self._indent
153+
return tmpl % (indent, self._namespace, self._rId, self._reltype,
127154
self._target, self.target_mode)
128155

129156

0 commit comments

Comments
 (0)