Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment