Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions Lib/test/test_xml_etree.py
Original file line number Diff line number Diff line change
Expand Up @@ -1144,14 +1144,9 @@ def check(p, expected, namespaces=None):

# tests from the xml specification
check("*", ['*'])
check("{ns}*", ['{ns}*'])
check("{}*", ['{}*'])
check("{*}tag", ['{*}tag'])
check("{*}*", ['{*}*'])
check("text()", ['text', '()'])
check("@name", ['@', 'name'])
check("@*", ['@', '*'])
check("@{ns}attr", ['@', '{ns}attr'])
check("para[1]", ['para', '[', '1', ']'])
check("para[last()]", ['para', '[', 'last', '()', ']'])
check("*/para", ['*', '/', 'para'])
Expand All @@ -1163,19 +1158,39 @@ def check(p, expected, namespaces=None):
check("//olist/item", ['//', 'olist', '/', 'item'])
check(".", ['.'])
check(".//para", ['.', '//', 'para'])
check(".//{*}tag", ['.', '//', '{*}tag'])
check("..", ['..'])
check("../@lang", ['..', '/', '@', 'lang'])
check("chapter[title]", ['chapter', '[', 'title', ']'])
check("employee[@secretary and @assistant]", ['employee',
'[', '@', 'secretary', '', 'and', '', '@', 'assistant', ']'])

# additional tests
check("@{ns}attr", ['@', '{ns}attr'])
check("{http://spam}egg", ['{http://spam}egg'])
check("./spam.egg", ['.', '/', 'spam.egg'])
check(".//{http://spam}egg", ['.', '//', '{http://spam}egg'])

# wildcard tags
check("{ns}*", ['{ns}*'])
check("{}*", ['{}*'])
check("{*}tag", ['{*}tag'])
check("{*}*", ['{*}*'])
check(".//{*}tag", ['.', '//', '{*}tag'])

# namespace prefix resolution
check("./xsd:type", ['.', '/', '{http://www.w3.org/2001/XMLSchema}type'],
{'xsd': 'http://www.w3.org/2001/XMLSchema'})
check("type", ['{http://www.w3.org/2001/XMLSchema}type'],
{'': 'http://www.w3.org/2001/XMLSchema'})
check("@xsd:type", ['@', '{http://www.w3.org/2001/XMLSchema}type'],
{'xsd': 'http://www.w3.org/2001/XMLSchema'})
check("@type", ['@', 'type'],
{'': 'http://www.w3.org/2001/XMLSchema'})
check("@{*}type", ['@', '{*}type'],
{'': 'http://www.w3.org/2001/XMLSchema'})
check("@{ns}attr", ['@', '{ns}attr'],
{'': 'http://www.w3.org/2001/XMLSchema',
'ns': 'http://www.w3.org/2001/XMLSchema'})

def test_processinginstruction(self):
# Test ProcessingInstruction directly
Expand Down
13 changes: 8 additions & 5 deletions Lib/xml/etree/ElementPath.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,27 @@

def xpath_tokenizer(pattern, namespaces=None):
default_namespace = namespaces.get('') if namespaces else None
parsing_attribute = False
for token in xpath_tokenizer_re.findall(pattern):
tag = token[1]
ttype, tag = token
if tag and tag[0] != "{":
if ":" in tag:
prefix, uri = tag.split(":", 1)
try:
if not namespaces:
raise KeyError
yield token[0], "{%s}%s" % (namespaces[prefix], uri)
yield ttype, "{%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)
elif default_namespace and not parsing_attribute:
yield ttype, "{%s}%s" % (default_namespace, tag)
else:
yield token
parsing_attribute = False
else:
yield token
parsing_attribute = ttype == '@'


def get_parent_map(context):
parent_map = context.parent_map
Expand All @@ -100,7 +104,6 @@ def get_parent_map(context):
return parent_map



def _is_wildcard_tag(tag):
return tag[:3] == '{*}' or tag[-2:] == '}*'

Expand Down