是否可以在xslt样式表的xpath谓词中使用lxml扩展功能?

时间:2018-07-21 04:20:44

标签: python xslt xpath lxml

扩展功能可用于xpath评估,但不适用于xslt转换。完全不支持这种使用吗?还是我会错过某些东西?

root = etree.XML('<a><b class="true">Haegar</b><b class="false">Baegar</b></a>')
doc = etree.ElementTree(root)

def match_class(context, arg):
    return 'class' in context.context_node.attrib and context.context_node.attrib['class'] == arg

ns = etree.FunctionNamespace('http://example.com/myother/functions')
ns.prefix = 'css'
ns['class'] = match_class

result = root.xpath("//*[css:class('true')]")
assert result[0].text == "Haegar"

xslt = etree.XSLT(etree.XML('''
   <stylesheet version="1.0"
          xmlns="http://www.w3.org/1999/XSL/Transform"
          xmlns:css="http://example.com/functions">
     <output method="text" encoding="ASCII"/>
     <template match="/">
        <apply-templates select="//*[css:class('true')]"/>
     </template>
   </stylesheet>
'''))

result = xslt(doc)
assert str(result) == "Haegar"

第一个断言通过。

但是对xslt(doc)的调用将恢复为lxml.etree.XSLTApplyError: Failed to evaluate the 'select' expression.,或者如果将xpath放入某个模板匹配项,则返回lxml.etree.XSLTApplyError: Error applying stylesheet

1 个答案:

答案 0 :(得分:1)

我认为您使用了错误的名称空间声明:

xmlns:es="http://example.com/functions"

您应该更改:

xmlns:css="http://example.com/myother/functions"

编辑

以下示例可以正常运行:

from lxml import etree

root = etree.XML(u'<a><b class="true">Haegar</b><b class="false">Baegar</b></a>')
doc = etree.ElementTree(root)


def match_class(context, arg):
    return 'class' in context.context_node.attrib and context.context_node.attrib['class'] == arg


ns = etree.FunctionNamespace('http://example.com/myother/functions')
ns.prefix = 'css'
ns['class'] = match_class

result = root.xpath("//*[css:class('true')]")
assert result[0].text == "Haegar"

xslt = etree.XSLT(etree.XML(u'''\
   <stylesheet version="1.0"
          xmlns="http://www.w3.org/1999/XSL/Transform"
          xmlns:css="http://example.com/myother/functions">
     <output method="text" encoding="ASCII"/>
     <template match="/">
        <apply-templates select="//*[css:class('true')]"/>
     </template>
   </stylesheet>
'''))

result = xslt(doc)
assert str(result) == "Haegar"

经过Python 2.7和lxml == 3.8.0的测试