Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
a tour of python's ElementTree path language
#from thatmattbone.com
import sys
import trace
import xml.etree.ElementTree
from xml.etree.ElementPath import prepare_child, xpath_tokenizer
TEST_DOC = """
<root>
<a>
<b value="2"/>
</a>
<a>
<b>
<c value="101"/>
</b>
</a>
<a value="will not be found"/>
<d>
<a>
<b value="also not found"/>
</a>
</d>
</root>"""
def brute_find(root):
"""
Given an ElementTree root find nodes matching
the path "a/b" without actually using the path language.
"""
def find_a(root):
for node in root:
if node.tag == "a":
yield node
def find_b(root):
for node in root:
if node.tag == "b":
yield node
for a_node in find_a(root):
for b_node in find_b(a_node):
yield b_node
def find(root, path):
"""
Find all nodes matching the specified path against
the specified root.
"""
return root.findall(path)
def trace_find(root, path):
"""
Find all nodes matching the specified path against
the specified root an trace the execution path along
the way, emitting this info to stdout.
"""
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
trace=1,
count=1)
return tracer.runfunc(find, root, path)
def tokenize(path):
"""
Return the tokenization of an ElementPath Expression.
"""
return list(xpath_tokenizer(path))
if __name__ == "__main__":
print(tokenize("a/b"))
root = xml.etree.ElementTree.fromstring(TEST_DOC)
print(list(brute_find(root)))
print(find(root, "a/b"))
#print(trace_find(doc, "a/b"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment