XPath functions and extensions

Asked by Victoria Dlugopolskaya

1) How can I add custom functions to the default namespace if they are named the same as the standard functions?

If I specify a namespace with a prefix, a custom function works fine:

from lxml import etree
_function_ns = etree.FunctionNamespace('http://example.com')
_function_ns.prefix = 'a'
def _dummy_count(arg):
 return 10
_function_ns['count'] = _dummy_count
_xml = etree.Element('structure')
print _xml.xpath('a:count()')

Output is '10.0'.

But if I add the function to the default namespace, I've got an error:

from lxml import etree
_function_ns = etree.FunctionNamespace(None)
def _dummy_count(arg):
 return 10
_function_ns['count'] = _dummy_count
_xml = etree.Element('structure')
print _xml.xpath('count()')

Output:

Traceback (most recent call last):
  File "/Users/onobrod/Desktop/function-namespace.py", line 7, in <module>
    print _xml.xpath('count()')
  File "src/lxml/etree.pyx", line 1575, in lxml.etree._Element.xpath
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Invalid number of arguments

Seems it doesn't recognise my 'count(arg)' function and use standard 'count(...)' instead.

It works fine with custom functions that are not conflicting with standard functions, but how can I specify a custom function with one of the standard functions name?

2) Seems I can use xpath functions from 'fn' namespace without declaring the namespace:

from lxml import etree
_xml = etree.Element('structure')
print _xml.xpath('string("test")')

Output is 'test'.

But I cannot call them as functions from 'fn' namespace:

from lxml import etree
_xml = etree.Element('structure')
print _xml.xpath('fn:string("test")')

Output:

Traceback (most recent call last):
  File "/Users/onobrod/Desktop/function-namespace.py", line 3, in <module>
    print _xml.xpath('fn:string("test")')
  File "src/lxml/etree.pyx", line 1575, in lxml.etree._Element.xpath
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Error in xpath expression

And I cannot use other xpath functions, like the functions from 'math' namespace:

from lxml import etree
_xml = etree.Element('structure')
print _xml.xpath('math:pi()')

Output:

Traceback (most recent call last):
  File "/Users/onobrod/Desktop/function-namespace.py", line 3, in <module>
    print _xml.xpath('math:pi()')
  File "src/lxml/etree.pyx", line 1575, in lxml.etree._Element.xpath
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Error in xpath expression

Is there a way to use xpath functions from 'fn', 'math' and other namespaces?

---

Python : sys.version_info(major=2, minor=7, micro=15, releaselevel='final', serial=0)
lxml.etree : (4, 3, 0, 0)
libxml used : (2, 9, 9)
libxml compiled : (2, 9, 9)
libxslt used : (1, 1, 32)
libxslt compiled : (1, 1, 32)

Question information

Language:
English Edit question
Status:
Expired
For:
Ubuntu lxml Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Launchpad Janitor (janitor) said :
#1

This question was expired because it remained in the 'Open' state without activity for the last 15 days.