| 72 | ) |
| 73 | |
| 74 | def xpath_tokenizer(pattern, namespaces=None): |
| 75 | default_namespace = namespaces.get('') if namespaces else None |
| 76 | parsing_attribute = False |
| 77 | for token in xpath_tokenizer_re.findall(pattern): |
| 78 | ttype, tag = token |
| 79 | if tag and tag[0] != "{": |
| 80 | if ":" in tag: |
| 81 | prefix, uri = tag.split(":", 1) |
| 82 | try: |
| 83 | if not namespaces: |
| 84 | raise KeyError |
| 85 | yield ttype, "{%s}%s" % (namespaces[prefix], uri) |
| 86 | except KeyError: |
| 87 | raise SyntaxError("prefix %r not found in prefix map" % prefix) from None |
| 88 | elif default_namespace and not parsing_attribute: |
| 89 | yield ttype, "{%s}%s" % (default_namespace, tag) |
| 90 | else: |
| 91 | yield token |
| 92 | parsing_attribute = False |
| 93 | else: |
| 94 | yield token |
| 95 | parsing_attribute = ttype == '@' |
| 96 | |
| 97 | |
| 98 | def get_parent_map(context): |