150 |
150 |
if last_only == None: last_only = create
|
151 |
151 |
if type(xpath) == str: xpath = parse(xpath)
|
152 |
152 |
|
153 |
|
if xpath == []: return parent
|
154 |
|
if create and not is_positive(xpath): return None
|
|
153 |
if xpath == []: return [parent]
|
|
154 |
if create and not is_positive(xpath): return []
|
155 |
155 |
doc = parent.ownerDocument
|
156 |
156 |
root = doc.documentElement
|
157 |
157 |
elem = xpath[0]
|
... | ... | |
172 |
172 |
is_match = elem.value == None or xml_dom.value(child) == elem.value
|
173 |
173 |
for attr in elem.keys:
|
174 |
174 |
if not is_match: break
|
175 |
|
is_match = (get(child, attr, False, last_only) != None)\
|
176 |
|
== is_positive(attr)
|
|
175 |
is_match = ((get(child, attr, False, last_only) != [])
|
|
176 |
== is_positive(attr))
|
177 |
177 |
if is_match:
|
178 |
178 |
nodes.append(child)
|
179 |
179 |
if limit != None and len(nodes) >= limit: break
|
180 |
|
try: node = nodes[0]
|
181 |
|
except IndexError: node = None
|
182 |
180 |
|
183 |
181 |
# Create node
|
184 |
|
if node == None:
|
185 |
|
if not create: return None
|
|
182 |
if nodes == []:
|
|
183 |
if not create: return []
|
186 |
184 |
if elem.is_attr:
|
187 |
185 |
parent.setAttribute(elem.name, '')
|
188 |
186 |
node = parent.getAttributeNode(elem.name)
|
189 |
187 |
else: node = parent.appendChild(doc.createElement(elem.name))
|
190 |
188 |
if elem.value != None: xml_dom.set_value(node, elem.value)
|
191 |
|
if create:
|
192 |
|
for attr in elem.keys + elem.attrs: get(node, attr, create, last_only)
|
|
189 |
nodes.append(node)
|
193 |
190 |
|
194 |
191 |
xpath = xpath[1:] # rest of XPath
|
195 |
192 |
|
196 |
|
# Follow pointer
|
197 |
|
if elem.is_ptr:
|
198 |
|
xpath = copy.deepcopy(xpath)
|
199 |
|
id_path = backward_id(xpath[instance_level])
|
200 |
|
if id_path != None: # backward (child-to-parent) pointer with ID key
|
201 |
|
id_path[0].name = expand_abbr(id_path[0].name, node.tagName)
|
202 |
|
set_value(id_path, xml_dom.get_id(node)) # modify id key of xpath
|
203 |
|
else: # forward (parent-to-child) pointer
|
204 |
|
id_ = xml_dom.value(node)
|
205 |
|
obj_xpath = obj(xpath) # target object
|
206 |
|
if id_ == None or get(root, obj_xpath, False, True) == None:
|
207 |
|
# no target or target keys don't match
|
208 |
|
if not create: return None
|
209 |
|
|
210 |
|
# Use last target object's ID + 1
|
211 |
|
obj_xpath[-1].keys = [] # just get by tag name
|
212 |
|
last = get(root, obj_xpath, False, True)
|
213 |
|
if last != None: id_ = str(int(xml_dom.get_id(last)) + 1)
|
214 |
|
else: id_ = '0'
|
215 |
|
|
216 |
|
# Will append if target keys didn't match.
|
217 |
|
# Use lookahead assertion to avoid this.
|
218 |
|
xml_dom.set_value(node, id_)
|
219 |
|
else: last_only = False
|
220 |
|
set_id(xpath, id_)
|
221 |
|
else: root = node
|
222 |
|
next = get(root, xpath, create, last_only)
|
|
193 |
next = []
|
|
194 |
for node in nodes:
|
|
195 |
# Create attrs
|
|
196 |
if create:
|
|
197 |
for attr in elem.keys + elem.attrs:
|
|
198 |
get(node, attr, create, last_only)
|
|
199 |
|
|
200 |
# Follow pointer
|
|
201 |
if elem.is_ptr:
|
|
202 |
xpath = copy.deepcopy(xpath)
|
|
203 |
id_path = backward_id(xpath[instance_level])
|
|
204 |
if id_path != None: # backward (child-to-parent) pointer with ID key
|
|
205 |
id_path[0].name = expand_abbr(id_path[0].name, node.tagName)
|
|
206 |
set_value(id_path, xml_dom.get_id(node)) # modify xpath's id key
|
|
207 |
else: # forward (parent-to-child) pointer
|
|
208 |
id_ = xml_dom.value(node)
|
|
209 |
obj_xpath = obj(xpath) # target object
|
|
210 |
if id_ == None or get(root, obj_xpath, False, True) == []:
|
|
211 |
# no target or target keys don't match
|
|
212 |
if not create: continue
|
|
213 |
|
|
214 |
# Use last target object's ID + 1
|
|
215 |
obj_xpath[-1].keys = [] # just get by tag name
|
|
216 |
last = get(root, obj_xpath, False, True)
|
|
217 |
if last != []: id_ = str(int(xml_dom.get_id(last[0])) + 1)
|
|
218 |
else: id_ = '0'
|
|
219 |
|
|
220 |
# Will append if target keys didn't match.
|
|
221 |
# Use lookahead assertion to avoid this.
|
|
222 |
xml_dom.set_value(node, id_)
|
|
223 |
else: last_only = False
|
|
224 |
set_id(xpath, id_)
|
|
225 |
else: root = node
|
|
226 |
next += get(root, xpath, create, last_only)
|
|
227 |
|
|
228 |
for branch in elem.other_branches:
|
|
229 |
branch = copy.deepcopy(branch)
|
|
230 |
set_value(branch, value(xpath))
|
|
231 |
next += get(node, branch, create, last_only)
|
223 |
232 |
|
224 |
|
for branch in elem.other_branches:
|
225 |
|
branch = copy.deepcopy(branch)
|
226 |
|
set_value(branch, value(xpath))
|
227 |
|
get(node, branch, create, last_only)
|
228 |
|
|
229 |
233 |
return next
|
230 |
234 |
|
231 |
235 |
def put_obj(root, xpath, id_, has_types, value=None):
|
xpath.py: get(): Added full support for returning multiple matches