summaryrefslogtreecommitdiff
path: root/Lib/xml/etree/ElementPath.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/xml/etree/ElementPath.py')
-rw-r--r--Lib/xml/etree/ElementPath.py33
1 files changed, 24 insertions, 9 deletions
diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py
index ef32917b14..0e3854f9db 100644
--- a/Lib/xml/etree/ElementPath.py
+++ b/Lib/xml/etree/ElementPath.py
@@ -71,16 +71,22 @@ xpath_tokenizer_re = re.compile(
)
def xpath_tokenizer(pattern, namespaces=None):
+ default_namespace = namespaces.get(None) if namespaces else None
for token in xpath_tokenizer_re.findall(pattern):
tag = token[1]
- if tag and tag[0] != "{" and ":" in tag:
- try:
+ if tag and tag[0] != "{":
+ if ":" in tag:
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) from None
+ try:
+ 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) from None
+ elif default_namespace:
+ yield token[0], "{%s}%s" % (default_namespace, tag)
+ else:
+ yield token
else:
yield token
@@ -264,10 +270,19 @@ class _SelectorContext:
def iterfind(elem, path, namespaces=None):
# compile selector pattern
- cache_key = (path, None if namespaces is None
- else tuple(sorted(namespaces.items())))
if path[-1:] == "/":
path = path + "*" # implicit all (FIXME: keep this?)
+
+ cache_key = (path,)
+ if namespaces:
+ if '' in namespaces:
+ raise ValueError("empty namespace prefix must be passed as None, not the empty string")
+ if None in namespaces:
+ cache_key += (namespaces[None],) + tuple(sorted(
+ item for item in namespaces.items() if item[0] is not None))
+ else:
+ cache_key += tuple(sorted(namespaces.items()))
+
try:
selector = _cache[cache_key]
except KeyError: