Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@goodmami
Last active September 2, 2021 16:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save goodmami/5ea94726785bcffc3db7 to your computer and use it in GitHub Desktop.
Save goodmami/5ea94726785bcffc3db7 to your computer and use it in GitHub Desktop.
ElementPath with default namespace support
def xpath_tokenizer(pattern, namespaces=None):
for token in xpath_tokenizer_re.findall(pattern):
tag = token[1]
if tag and tag[0] != "{" and ":" in tag:
try:
prefix, uri = tag.split(":", 1)
if not namespaces:
raise KeyError
yield token[0], "{%s}%s" % (namespaces[prefix], uri)
except KeyError:
raise SyntaxError("prefix %r not found in prefix map" % prefix)
else:
yield token
def xpath_tokenizer(pattern, namespaces=None):
for token in xpath_tokenizer_re.findall(pattern):
tag = token[1]
if tag and tag[0] != "{":
try:
if ':' in tag:
prefix, uri = tag.split(":", 1)
else:
prefix, uri = '', tag
if not namespaces:
raise KeyError
yield token[0], "{%s}%s" % (namespaces[prefix], uri)
except KeyError:
raise SyntaxError("prefix %r not found in prefix map" % prefix)
else:
yield token
from xml.etree import ElementTree as ET
doc = ET.fromstring('''
<root xmlns="http://example.com" xmlns:pre="http://example.com/prefix">
<a>1</a>
<pre:b>2</pre:b>
</root>
''')
nsmap = {'': 'http://example.com', 'pre':'http://example.com/prefix'}
doc.find('.//a') # finds nothing
doc.find('.//a', namespaces=nsmap) # finds nothing
doc.find('.//{http://example.com}a') # works, but yuck
doc.find('.//pre:b', namespaces=nsmap) # this works, though
@goodmami
Copy link
Author

goodmami commented Nov 4, 2015

ElementPath-xpath_tokenizer-original.py is the function from the xml.etree.ElementPath module in Python 3.5. ElementPath-xpath_tokenizer-updated.py is a version that also adds URIs for the default namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment