|
71 | 71 | ) |
72 | 72 |
|
73 | 73 | def xpath_tokenizer(pattern, namespaces=None): |
| 74 | + default_namespace = namespaces.get(None) if namespaces else None |
74 | 75 | for token in xpath_tokenizer_re.findall(pattern): |
75 | 76 | tag = token[1] |
76 | | - if tag and tag[0] != "{" and ":" in tag: |
77 | | - try: |
| 77 | + if tag and tag[0] != "{": |
| 78 | + if ":" in tag: |
78 | 79 | prefix, uri = tag.split(":", 1) |
79 | | - if not namespaces: |
80 | | - raise KeyError |
81 | | - yield token[0], "{%s}%s" % (namespaces[prefix], uri) |
82 | | - except KeyError: |
83 | | - raise SyntaxError("prefix %r not found in prefix map" % prefix) from None |
| 80 | + try: |
| 81 | + if not namespaces: |
| 82 | + raise KeyError |
| 83 | + yield token[0], "{%s}%s" % (namespaces[prefix], uri) |
| 84 | + except KeyError: |
| 85 | + raise SyntaxError("prefix %r not found in prefix map" % prefix) from None |
| 86 | + elif default_namespace: |
| 87 | + yield token[0], "{%s}%s" % (default_namespace, tag) |
| 88 | + else: |
| 89 | + yield token |
84 | 90 | else: |
85 | 91 | yield token |
86 | 92 |
|
@@ -264,10 +270,19 @@ def __init__(self, root): |
264 | 270 |
|
265 | 271 | def iterfind(elem, path, namespaces=None): |
266 | 272 | # compile selector pattern |
267 | | - cache_key = (path, None if namespaces is None |
268 | | - else tuple(sorted(namespaces.items()))) |
269 | 273 | if path[-1:] == "/": |
270 | 274 | path = path + "*" # implicit all (FIXME: keep this?) |
| 275 | + |
| 276 | + cache_key = (path,) |
| 277 | + if namespaces: |
| 278 | + if '' in namespaces: |
| 279 | + raise ValueError("empty namespace prefix must be passed as None, not the empty string") |
| 280 | + if None in namespaces: |
| 281 | + cache_key += (namespaces[None],) + tuple(sorted( |
| 282 | + item for item in namespaces.items() if item[0] is not None)) |
| 283 | + else: |
| 284 | + cache_key += tuple(sorted(namespaces.items())) |
| 285 | + |
271 | 286 | try: |
272 | 287 | selector = _cache[cache_key] |
273 | 288 | except KeyError: |
|
0 commit comments