是否可以在 xslt 样式表的 xpath 谓词中使用 lxml 扩展函数?
Is it possible to use lxml extension functions in xpath predicates in xslt stylesheet?
扩展函数适用于 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.
,或者 lxml.etree.XSLTApplyError: Error applying stylesheet
如果将 xpath 放入某个模板匹配中。
我认为你使用了错误的命名空间声明:
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 测试
扩展函数适用于 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.
,或者 lxml.etree.XSLTApplyError: Error applying stylesheet
如果将 xpath 放入某个模板匹配中。
我认为你使用了错误的命名空间声明:
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 测试