Skip to content

searching for XML elements with position predicates does not work at all when namespaces are involved. #132637

Open

Description

@joooeey

Bug report

Bug description:

Failure with namespaces:

Python 3.12.7 | packaged by conda-forge | (main, Oct  4 2024, 16:05:46) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as ET
>>> ET.XML('<a xmlns="http://www.example.com/default-schema"><b/><b/></a>').find("./b[1]", {"": "http://www.example.com/default-schema"})
>>> ET.XML('<a xmlns="http://www.example.com/default-schema"><b/><b/></a>').find("./b[last()]", {"": "http://www.example.com/default-schema"})
Traceback (most recent call last):
  File "/home/lukas/miniforge3/envs/roads/lib/python3.12/xml/etree/ElementPath.py", line 370, in iterfind
    selector = _cache[cache_key]
               ~~~~~~^^^^^^^^^^^
KeyError: ('./b[last()]', ('', 'http://www.example.com/default-schema'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lukas/miniforge3/envs/roads/lib/python3.12/xml/etree/ElementPath.py", line 405, in find
    return next(iterfind(elem, path, namespaces), None)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lukas/miniforge3/envs/roads/lib/python3.12/xml/etree/ElementPath.py", line 384, in iterfind
    selector.append(ops[token[0]](next, token))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lukas/miniforge3/envs/roads/lib/python3.12/xml/etree/ElementPath.py", line 315, in prepare_predicate
    raise SyntaxError("unsupported function")
SyntaxError: unsupported function
>>> ET.XML('<a xmlns="http://www.example.com/default-schema"><b/><b/></a>').find("./b", {"": "http://www.example.com/default-schema"})
<Element '{http://www.example.com/default-schema}b' at 0x750110149b20>
>>>
  • searching by integer position yields None
  • searching with the predicate [last()] fails with "unsupported function"

This works fine when no namespaces are involved:

\>>> ET.XML('<a><b/><b/></a>').find("./b[1]")
<Element 'b' at 0x7501101498a0>
>>> ET.XML('<a><b/><b/></a>').find("./b[last()]")
<Element 'b' at 0x7501101499e0>
>>> 

With namespaces I would expect similar results.

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions