bpo-28238: Implement "{*}tag" and "{ns}*" wildcard tag selection supp… · python/cpython@4754168

@@ -1137,16 +1137,21 @@ def test_doctype_public(self):

11371137

def test_xpath_tokenizer(self):

11381138

# Test the XPath tokenizer.

11391139

from xml.etree import ElementPath

1140-

def check(p, expected):

1140+

def check(p, expected, namespaces=None):

11411141

self.assertEqual([op or tag

1142-

for op, tag in ElementPath.xpath_tokenizer(p)],

1142+

for op, tag in ElementPath.xpath_tokenizer(p, namespaces)],

11431143

expected)

1144114411451145

# tests from the xml specification

11461146

check("*", ['*'])

1147+

check("{ns}*", ['{ns}*'])

1148+

check("{}*", ['{}*'])

1149+

check("{*}tag", ['{*}tag'])

1150+

check("{*}*", ['{*}*'])

11471151

check("text()", ['text', '()'])

11481152

check("@name", ['@', 'name'])

11491153

check("@*", ['@', '*'])

1154+

check("@{ns}attr", ['@', '{ns}attr'])

11501155

check("para[1]", ['para', '[', '1', ']'])

11511156

check("para[last()]", ['para', '[', 'last', '()', ']'])

11521157

check("*/para", ['*', '/', 'para'])

@@ -1158,6 +1163,7 @@ def check(p, expected):

11581163

check("//olist/item", ['//', 'olist', '/', 'item'])

11591164

check(".", ['.'])

11601165

check(".//para", ['.', '//', 'para'])

1166+

check(".//{*}tag", ['.', '//', '{*}tag'])

11611167

check("..", ['..'])

11621168

check("../@lang", ['..', '/', '@', 'lang'])

11631169

check("chapter[title]", ['chapter', '[', 'title', ']'])

@@ -1168,6 +1174,8 @@ def check(p, expected):

11681174

check("{http://spam}egg", ['{http://spam}egg'])

11691175

check("./spam.egg", ['.', '/', 'spam.egg'])

11701176

check(".//{http://spam}egg", ['.', '//', '{http://spam}egg'])

1177+

check("./xsd:type", ['.', '/', '{http://www.w3.org/2001/XMLSchema}type'],

1178+

{'xsd': 'http://www.w3.org/2001/XMLSchema'})

1171117911721180

def test_processinginstruction(self):

11731181

# Test ProcessingInstruction directly

@@ -2669,6 +2677,50 @@ def test_findall_different_nsmaps(self):

26692677

self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)

26702678

self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1)

267126792680+

def test_findall_wildcard(self):

2681+

root = ET.XML('''

2682+

<a xmlns:x="X" xmlns:y="Y">

2683+

<x:b><c/></x:b>

2684+

<b/>

2685+

<c><x:b/><b/></c><y:b/>

2686+

</a>''')

2687+

root.append(ET.Comment('test'))

2688+2689+

self.assertEqual(summarize_list(root.findall("{*}b")),

2690+

['{X}b', 'b', '{Y}b'])

2691+

self.assertEqual(summarize_list(root.findall("{*}c")),

2692+

['c'])

2693+

self.assertEqual(summarize_list(root.findall("{X}*")),

2694+

['{X}b'])

2695+

self.assertEqual(summarize_list(root.findall("{Y}*")),

2696+

['{Y}b'])

2697+

self.assertEqual(summarize_list(root.findall("{}*")),

2698+

['b', 'c'])

2699+

self.assertEqual(summarize_list(root.findall("{}b")), # only for consistency

2700+

['b'])

2701+

self.assertEqual(summarize_list(root.findall("{}b")),

2702+

summarize_list(root.findall("b")))

2703+

self.assertEqual(summarize_list(root.findall("{*}*")),

2704+

['{X}b', 'b', 'c', '{Y}b'])

2705+

# This is an unfortunate difference, but that's how find('*') works.

2706+

self.assertEqual(summarize_list(root.findall("{*}*") + [root[-1]]),

2707+

summarize_list(root.findall("*")))

2708+2709+

self.assertEqual(summarize_list(root.findall(".//{*}b")),

2710+

['{X}b', 'b', '{X}b', 'b', '{Y}b'])

2711+

self.assertEqual(summarize_list(root.findall(".//{*}c")),

2712+

['c', 'c'])

2713+

self.assertEqual(summarize_list(root.findall(".//{X}*")),

2714+

['{X}b', '{X}b'])

2715+

self.assertEqual(summarize_list(root.findall(".//{Y}*")),

2716+

['{Y}b'])

2717+

self.assertEqual(summarize_list(root.findall(".//{}*")),

2718+

['c', 'b', 'c', 'b'])

2719+

self.assertEqual(summarize_list(root.findall(".//{}b")), # only for consistency

2720+

['b', 'b'])

2721+

self.assertEqual(summarize_list(root.findall(".//{}b")),

2722+

summarize_list(root.findall(".//b")))

2723+26722724

def test_bad_find(self):

26732725

e = ET.XML(SAMPLE_XML)

26742726

with self.assertRaisesRegex(SyntaxError, 'cannot use absolute path'):