xmlbuilder: Clarify the node 'pretty' helper function

This commit is contained in:
Cole Robinson 2016-07-18 13:23:43 -04:00
parent d8a0a78805
commit 559e813b96

View File

@ -98,14 +98,13 @@ def _get_xpath_node(ctx, xpath):
return (node and node[0] or None) return (node and node[0] or None)
def _build_xpath_node(ctx, xpath, addnode=None): def _add_pretty_child(parentnode, newnode):
""" """
Build all nodes required to set an xpath. If we have XML <foo/>, and want Add 'newnode' as a child of 'parentnode', but try to preserve
to set xpath /foo/bar/baz@booyeah, we create node 'bar' and 'baz' whitespace and nicely format the result.
returning the last node created.
""" """
parentpath = "" def node_is_text(n):
parentnode = None return bool(n and n.type == "text" and not n.content.count("<"))
def prevSibling(node): def prevSibling(node):
parent = node.get_parent() parent = node.get_parent()
@ -120,47 +119,51 @@ def _build_xpath_node(ctx, xpath, addnode=None):
return None return None
def make_node(parentnode, newnode): sib = parentnode.get_last()
# Add the needed parent node, try to preserve whitespace by if not node_is_text(sib):
# looking for a starting TEXT node, and copying it # This case is when we add a child element to a node for the
def node_is_text(n): # first time, like:
return bool(n and n.type == "text" and not n.content.count("<")) #
# <features/>
sib = parentnode.get_last()
if not node_is_text(sib):
# This case is when we add a child element to a node for the
# first time, like:
#
# <features/>
# to
# <features>
# <acpi/>
# </features>
prevsib = prevSibling(parentnode)
if node_is_text(prevsib):
sib = libxml2.newText(prevsib.content)
else:
sib = libxml2.newText("\n")
parentnode.addChild(sib)
# This case is adding a child element to an already properly
# spaced element. Example:
# <features>
# <acpi/>
# </features>
# to # to
# <features> # <features>
# <acpi/> # <acpi/>
# <apic/>
# </features> # </features>
sib = parentnode.get_last() prevsib = prevSibling(parentnode)
content = sib.content if node_is_text(prevsib):
sib = sib.addNextSibling(libxml2.newText(" ")) sib = libxml2.newText(prevsib.content)
txt = libxml2.newText(content) else:
sib = libxml2.newText("\n")
parentnode.addChild(sib)
sib.addNextSibling(newnode) # This case is adding a child element to an already properly
newnode.addNextSibling(txt) # spaced element. Example:
return newnode # <features>
# <acpi/>
# </features>
# to
# <features>
# <acpi/>
# <apic/>
# </features>
sib = parentnode.get_last()
content = sib.content
sib = sib.addNextSibling(libxml2.newText(" "))
txt = libxml2.newText(content)
sib.addNextSibling(newnode)
newnode.addNextSibling(txt)
return newnode
def _build_xpath_node(ctx, xpath, addnode=None):
"""
Build all nodes required to set an xpath. If we have XML <foo/>, and want
to set xpath /foo/bar/baz@booyeah, we create node 'bar' and 'baz'
returning the last node created.
"""
parentpath = ""
parentnode = None
nodelist = xpath.split("/") nodelist = xpath.split("/")
for nodename in nodelist: for nodename in nodelist:
@ -192,10 +195,10 @@ def _build_xpath_node(ctx, xpath, addnode=None):
nodename = nodename[:nodename.index("[")] nodename = nodename[:nodename.index("[")]
newnode = libxml2.newNode(nodename) newnode = libxml2.newNode(nodename)
parentnode = make_node(parentnode, newnode) parentnode = _add_pretty_child(parentnode, newnode)
if addnode: if addnode:
parentnode = make_node(parentnode, addnode) parentnode = _add_pretty_child(parentnode, addnode)
return parentnode return parentnode