Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XPath 2/3 expression min(.//row/count(entry)) doesn't parse with XPath3Parser: elementpath.exceptions.ElementPathTypeError: 'entry' proxy function at line 1, column 18: [err:XPST0017] unknown function 'entry' #78

Open
martin-honnen opened this issue Oct 20, 2024 · 1 comment

Comments

@martin-honnen
Copy link
Contributor

I find that the XPath 2 and 3 expression min(.//row/count(entry)) doesn't parse with the XPath3Parser (it parses with the XPath2 default parser), the error I get is elementpath.exceptions.ElementPathTypeError: 'entry' proxy function at line 1, column 18: [err:XPST0017] unknown function 'entry'.

Example Python code:

from elementpath import select
from elementpath.xpath3 import XPath3Parser

from xml.etree import ElementTree

root = ElementTree.XML('''      <table frame="all" rowsep="1" colsep="1" id="flowers_table">
        <title>Flowers</title>
        <tgroup cols="3">
          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
          <thead>
            <row>
              <entry>Flower</entry>
              <entry>Type</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>Chrysanthemum</entry>
              <entry>perennial</entry>
              <entry>well drained</entry>
            </row>
            <row>
              <entry>Gardenia</entry>
              <entry>perennial</entry>
            </row>
            <row>
              <entry>Gerbera</entry>
              <entry>annual</entry>
              <entry>sandy, well-drained</entry>
            </row>
            <row>
              <entry>Iris</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
''')

results = select(root, 'min(.//row/count(entry))')

print(results)

results = select(root, 'min(.//row/count(entry))', parser=XPath3Parser)

print(results)

The first select using the default XPath 2 parser works fine and the output of the subsequent print is 1, but the following code fails with

Traceback (most recent call last):
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\elementpath-test1.py", line 45, in <module>
    results = select(root, 'min(.//row/count(entry))', parser=XPath3Parser)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath_selectors.py", line 53, in select
    root_token = _parser.parse(path)
                 ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath2\xpath2_parser.py", line 510, in parse
    root_token = super(XPath1Parser, self).parse(source)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\tdop.py", line 497, in parse
    root_token = self.expression()
                 ^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\tdop.py", line 622, in expression
    left = self.token.nud()
           ^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath_tokens.py", line 1454, in nud
    self._items[k:] = self.parser.expression(5),
                      ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\tdop.py", line 625, in expression
    left = self.token.led(left)
           ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath1\_xpath1_operators.py", line 718, in led_child_or_descendant_path
    self[:] = left, self.parser.expression(75)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\tdop.py", line 622, in expression
    left = self.token.nud()
           ^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath_tokens.py", line 1454, in nud
    self._items[k:] = self.parser.expression(5),
                      ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\tdop.py", line 622, in expression
    left = self.token.nud()
           ^^^^^^^^^^^^^^^^
  File "C:\Users\marti\PycharmProjects\Pyschematron-test1\.venv\Lib\site-packages\elementpath\xpath_tokens.py", line 1204, in nud
    raise self.error('XPST0017', msg) from None
elementpath.exceptions.ElementPathTypeError: 'entry' proxy function at line 1, column 18: [err:XPST0017] unknown function 'entry'
brunato added a commit that referenced this issue Oct 27, 2024
  - Fix for issue #78
  - Fix proxy() class method to use a different class name from
    the original token
  - Remove useless MutableSequence.register(): tokens are already
    MutableSequence instances
@brunato
Copy link
Member

brunato commented Oct 27, 2024

Hi,
this is a problem of names collisions, that is implicit in XPath. The version 4.6.0 should fix this and other ambiguities, also with operators.
thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants