initial commit after bringing over cleaned up code and testing some examples
This commit is contained in:
parent
c4858e6e0d
commit
00f4ebf5a9
93 changed files with 15189 additions and 13083 deletions
338
daemon/core/xml/xmlutils.py
Normal file
338
daemon/core/xml/xmlutils.py
Normal file
|
@ -0,0 +1,338 @@
|
|||
from xml.dom.minidom import Node
|
||||
|
||||
from core.misc import log
|
||||
from core.netns import nodes
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
def add_elements_from_list(dom, parent, iterable, name, attr_name):
|
||||
"""
|
||||
XML helper to iterate through a list and add items to parent using tags
|
||||
of the given name and the item value as an attribute named attr_name.
|
||||
Example: addelementsfromlist(dom, parent, ('a','b','c'), "letter", "value")
|
||||
<parent>
|
||||
<letter value="a"/>
|
||||
<letter value="b"/>
|
||||
<letter value="c"/>
|
||||
</parent>
|
||||
"""
|
||||
for item in iterable:
|
||||
element = dom.createElement(name)
|
||||
element.setAttribute(attr_name, item)
|
||||
parent.appendChild(element)
|
||||
|
||||
|
||||
def add_text_elements_from_list(dom, parent, iterable, name, attrs):
|
||||
"""
|
||||
XML helper to iterate through a list and add items to parent using tags
|
||||
of the given name, attributes specified in the attrs tuple, and having the
|
||||
text of the item within the tags.
|
||||
Example: addtextelementsfromlist(dom, parent, ('a','b','c'), "letter",
|
||||
(('show','True'),))
|
||||
<parent>
|
||||
<letter show="True">a</letter>
|
||||
<letter show="True">b</letter>
|
||||
<letter show="True">c</letter>
|
||||
</parent>
|
||||
"""
|
||||
for item in iterable:
|
||||
element = dom.createElement(name)
|
||||
for k, v in attrs:
|
||||
element.setAttribute(k, v)
|
||||
parent.appendChild(element)
|
||||
txt = dom.createTextNode(item)
|
||||
element.appendChild(txt)
|
||||
|
||||
|
||||
def add_text_elements_from_tuples(dom, parent, iterable, attrs=()):
|
||||
"""
|
||||
XML helper to iterate through a list of tuples and add items to
|
||||
parent using tags named for the first tuple element,
|
||||
attributes specified in the attrs tuple, and having the
|
||||
text of second tuple element.
|
||||
Example: addtextelementsfromtuples(dom, parent,
|
||||
(('first','a'),('second','b'),('third','c')),
|
||||
(('show','True'),))
|
||||
<parent>
|
||||
<first show="True">a</first>
|
||||
<second show="True">b</second>
|
||||
<third show="True">c</third>
|
||||
</parent>
|
||||
"""
|
||||
for name, value in iterable:
|
||||
element = dom.createElement(name)
|
||||
for k, v in attrs:
|
||||
element.setAttribute(k, v)
|
||||
parent.appendChild(element)
|
||||
txt = dom.createTextNode(value)
|
||||
element.appendChild(txt)
|
||||
|
||||
|
||||
def get_text_elements_to_list(parent):
|
||||
"""
|
||||
XML helper to parse child text nodes from the given parent and return
|
||||
a list of (key, value) tuples.
|
||||
"""
|
||||
r = []
|
||||
for n in parent.childNodes:
|
||||
if n.nodeType != Node.ELEMENT_NODE:
|
||||
continue
|
||||
k = str(n.nodeName)
|
||||
v = '' # sometimes want None here?
|
||||
for c in n.childNodes:
|
||||
if c.nodeType != Node.TEXT_NODE:
|
||||
continue
|
||||
v = str(c.nodeValue)
|
||||
break
|
||||
r.append((k, v))
|
||||
return r
|
||||
|
||||
|
||||
def add_param_to_parent(dom, parent, name, value):
|
||||
"""
|
||||
XML helper to add a <param name="name" value="value"/> tag to the parent
|
||||
element, when value is not None.
|
||||
"""
|
||||
if value is None:
|
||||
return None
|
||||
p = dom.createElement("param")
|
||||
parent.appendChild(p)
|
||||
p.setAttribute("name", name)
|
||||
p.setAttribute("value", "%s" % value)
|
||||
return p
|
||||
|
||||
|
||||
def add_text_param_to_parent(dom, parent, name, value):
|
||||
"""
|
||||
XML helper to add a <param name="name">value</param> tag to the parent
|
||||
element, when value is not None.
|
||||
"""
|
||||
if value is None:
|
||||
return None
|
||||
p = dom.createElement("param")
|
||||
parent.appendChild(p)
|
||||
p.setAttribute("name", name)
|
||||
txt = dom.createTextNode(value)
|
||||
p.appendChild(txt)
|
||||
return p
|
||||
|
||||
|
||||
def add_param_list_to_parent(dom, parent, name, values):
|
||||
"""
|
||||
XML helper to return a parameter list and optionally add it to the
|
||||
parent element:
|
||||
<paramlist name="name">
|
||||
<item value="123">
|
||||
<item value="456">
|
||||
</paramlist>
|
||||
"""
|
||||
if values is None:
|
||||
return None
|
||||
p = dom.createElement("paramlist")
|
||||
if parent:
|
||||
parent.appendChild(p)
|
||||
p.setAttribute("name", name)
|
||||
for v in values:
|
||||
item = dom.createElement("item")
|
||||
item.setAttribute("value", str(v))
|
||||
p.appendChild(item)
|
||||
return p
|
||||
|
||||
|
||||
def get_one_element(dom, name):
|
||||
e = dom.getElementsByTagName(name)
|
||||
if len(e) == 0:
|
||||
return None
|
||||
return e[0]
|
||||
|
||||
|
||||
def iter_descendants(dom, max_depth=0):
|
||||
"""
|
||||
Iterate over all descendant element nodes in breadth first order.
|
||||
Only consider nodes up to max_depth deep when max_depth is greater
|
||||
than zero.
|
||||
"""
|
||||
nodes = [dom]
|
||||
depth = 0
|
||||
current_depth_nodes = 1
|
||||
next_depth_nodes = 0
|
||||
while nodes:
|
||||
n = nodes.pop(0)
|
||||
for child in n.childNodes:
|
||||
if child.nodeType == Node.ELEMENT_NODE:
|
||||
yield child
|
||||
nodes.append(child)
|
||||
next_depth_nodes += 1
|
||||
current_depth_nodes -= 1
|
||||
if current_depth_nodes == 0:
|
||||
depth += 1
|
||||
if max_depth > 0 and depth == max_depth:
|
||||
return
|
||||
current_depth_nodes = next_depth_nodes
|
||||
next_depth_nodes = 0
|
||||
|
||||
|
||||
def iter_matching_descendants(dom, match_function, max_depth=0):
|
||||
"""
|
||||
Iterate over descendant elements where matchFunction(descendant)
|
||||
returns true. Only consider nodes up to max_depth deep when
|
||||
max_depth is greater than zero.
|
||||
"""
|
||||
for d in iter_descendants(dom, max_depth):
|
||||
if match_function(d):
|
||||
yield d
|
||||
|
||||
|
||||
def iter_descendants_with_name(dom, tag_name, max_depth=0):
|
||||
"""
|
||||
Iterate over descendant elements whose name is contained in
|
||||
tagName (or is named tagName if tagName is a string). Only
|
||||
consider nodes up to max_depth deep when max_depth is greater than
|
||||
zero.
|
||||
"""
|
||||
if isinstance(tag_name, basestring):
|
||||
tag_name = (tag_name,)
|
||||
|
||||
def match(d):
|
||||
return d.tagName in tag_name
|
||||
|
||||
return iter_matching_descendants(dom, match, max_depth)
|
||||
|
||||
|
||||
def iter_descendants_with_attribute(dom, tag_name, attr_name, attr_value, max_depth=0):
|
||||
"""
|
||||
Iterate over descendant elements whose name is contained in
|
||||
tagName (or is named tagName if tagName is a string) and have an
|
||||
attribute named attrName with value attrValue. Only consider
|
||||
nodes up to max_depth deep when max_depth is greater than zero.
|
||||
"""
|
||||
if isinstance(tag_name, basestring):
|
||||
tag_name = (tag_name,)
|
||||
|
||||
def match(d):
|
||||
return d.tagName in tag_name and \
|
||||
d.getAttribute(attr_name) == attr_value
|
||||
|
||||
return iter_matching_descendants(dom, match, max_depth)
|
||||
|
||||
|
||||
def iter_children(dom, node_type):
|
||||
"""
|
||||
Iterate over all child elements of the given type.
|
||||
"""
|
||||
for child in dom.childNodes:
|
||||
if child.nodeType == node_type:
|
||||
yield child
|
||||
|
||||
|
||||
def get_text_child(dom):
|
||||
"""
|
||||
Return the text node of the given element.
|
||||
"""
|
||||
for child in iter_children(dom, Node.TEXT_NODE):
|
||||
return str(child.nodeValue)
|
||||
return None
|
||||
|
||||
|
||||
def get_child_text_trim(dom):
|
||||
text = get_text_child(dom)
|
||||
if text:
|
||||
text = text.strip()
|
||||
return text
|
||||
|
||||
|
||||
def get_params_set_attrs(dom, param_names, target):
|
||||
"""
|
||||
XML helper to get <param name="name" value="value"/> tags and set
|
||||
the attribute in the target object. String type is used. Target object
|
||||
attribute is unchanged if the XML attribute is not present.
|
||||
"""
|
||||
params = dom.getElementsByTagName("param")
|
||||
for param in params:
|
||||
param_name = param.getAttribute("name")
|
||||
value = param.getAttribute("value")
|
||||
if value is None:
|
||||
continue # never reached?
|
||||
if param_name in param_names:
|
||||
setattr(target, param_name, str(value))
|
||||
|
||||
|
||||
def xml_type_to_node_class(session, type):
|
||||
"""
|
||||
Helper to convert from a type string to a class name in nodes.*.
|
||||
"""
|
||||
if hasattr(nodes, type):
|
||||
# TODO: remove and use a mapping to known nodes
|
||||
logger.error("using eval to retrieve node type: %s", type)
|
||||
return eval("nodes.%s" % type)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def iter_children_with_name(dom, tag_name):
|
||||
return iter_descendants_with_name(dom, tag_name, 1)
|
||||
|
||||
|
||||
def iter_children_with_attribute(dom, tag_name, attr_name, attr_value):
|
||||
return iter_descendants_with_attribute(dom, tag_name, attr_name, attr_value, 1)
|
||||
|
||||
|
||||
def get_first_child_by_tag_name(dom, tag_name):
|
||||
"""
|
||||
Return the first child element whose name is contained in tagName
|
||||
(or is named tagName if tagName is a string).
|
||||
"""
|
||||
for child in iter_children_with_name(dom, tag_name):
|
||||
return child
|
||||
return None
|
||||
|
||||
|
||||
def get_first_child_text_by_tag_name(dom, tag_name):
|
||||
"""
|
||||
Return the corresponding text of the first child element whose
|
||||
name is contained in tagName (or is named tagName if tagName is a
|
||||
string).
|
||||
"""
|
||||
child = get_first_child_by_tag_name(dom, tag_name)
|
||||
if child:
|
||||
return get_text_child(child)
|
||||
return None
|
||||
|
||||
|
||||
def get_first_child_text_trim_by_tag_name(dom, tag_name):
|
||||
text = get_first_child_text_by_tag_name(dom, tag_name)
|
||||
if text:
|
||||
text = text.strip()
|
||||
return text
|
||||
|
||||
|
||||
def get_first_child_with_attribute(dom, tag_name, attr_name, attr_value):
|
||||
"""
|
||||
Return the first child element whose name is contained in tagName
|
||||
(or is named tagName if tagName is a string) that has an attribute
|
||||
named attrName with value attrValue.
|
||||
"""
|
||||
for child in \
|
||||
iter_children_with_attribute(dom, tag_name, attr_name, attr_value):
|
||||
return child
|
||||
return None
|
||||
|
||||
|
||||
def get_first_child_text_with_attribute(dom, tag_name, attr_name, attr_value):
|
||||
"""
|
||||
Return the corresponding text of the first child element whose
|
||||
name is contained in tagName (or is named tagName if tagName is a
|
||||
string) that has an attribute named attrName with value attrValue.
|
||||
"""
|
||||
child = get_first_child_with_attribute(dom, tag_name, attr_name, attr_value)
|
||||
if child:
|
||||
return get_text_child(child)
|
||||
return None
|
||||
|
||||
|
||||
def get_first_child_text_trim_with_attribute(dom, tag_name, attr_name, attr_value):
|
||||
text = get_first_child_text_with_attribute(dom, tag_name, attr_name, attr_value)
|
||||
if text:
|
||||
text = text.strip()
|
||||
return text
|
Loading…
Add table
Add a link
Reference in a new issue