扩展功能可用于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
。
答案 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的测试