Python 如何从XPath函数返回文本片段?
假设我使用Python 如何从XPath函数返回文本片段?,python,lxml,Python,Lxml,假设我使用lxml(使用libxml和libxslt)从XSL转换调用XPath函数,例如: ... 从这个函数中,我想返回一个XML片段,它包含以下内容: some sample <em>text</em> 一些示例文本 python函数my_func使用lxml正确设置,可通过XSL样式表获得,并使用lxml.html.fragments\u fromstring获得以下格式的结果: ['some sample',] 如何返回此列表,以便稍后在XSL转换中从变
lxml
(使用libxml
和libxslt
)从XSL转换调用XPath函数,例如:
...
从这个函数中,我想返回一个XML片段,它包含以下内容:
some sample <em>text</em>
一些示例文本
python函数my_func
使用lxml
正确设置,可通过XSL样式表获得,并使用lxml.html.fragments\u fromstring
获得以下格式的结果:
['some sample',]
如何返回此列表,以便稍后在XSL转换中从变量中使用它,就好像它是直接从XSL上下文中的XPath表达式中收集的一样?似乎每当我将字符串列表传递回XSL处理器时,lxml就会抛出一个异常。第一件事是定义函数。它需要以项目列表的形式返回节点集。这些项可能包括元素(也包括注释和处理指令)、字符串和元组 硬编码示例可能如下所示:
from lxml import etree
def myFunc(context, parm):
em = etree.Element('em')
em.text = 'text'
return ['some sample ', em]
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myns="http://example.org/myNamespace">
<xsl:template match="/">
<xsl:variable name="result" select="myns:my-func(./*)" />
<xsl:for-each select="$result">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
root = etree.XML('<root></root>')
doc = etree.ElementTree(root)
transform = etree.XSLT(etree.XML(xslt))
res = transform(doc)
请注意,在这种情况下,parm参数不是必需的,但我在这里包含它是为了匹配您的示例代码,该代码在调用myns:my func时传递参数
如果您想使用fragments_fromstring来构建节点集,而不是手动构建它,那么函数定义会变得更简单
def myFunc(context, parm):
import lxml.html
return lxml.html.fragments_fromstring('some sample <em>text</em>')
最后,您可以在XSLT样式表中使用它,如下所示:
from lxml import etree
def myFunc(context, parm):
em = etree.Element('em')
em.text = 'text'
return ['some sample ', em]
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myns="http://example.org/myNamespace">
<xsl:template match="/">
<xsl:variable name="result" select="myns:my-func(./*)" />
<xsl:for-each select="$result">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
root = etree.XML('<root></root>')
doc = etree.ElementTree(root)
transform = etree.XSLT(etree.XML(xslt))
res = transform(doc)
注意样式表中使用的名称空间URL必须与FunctionNamespace中注册的URL匹配
现在假设您已将此样式表加载到名为xslt的字符串中,示例转换可能如下所示:
from lxml import etree
def myFunc(context, parm):
em = etree.Element('em')
em.text = 'text'
return ['some sample ', em]
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myns="http://example.org/myNamespace">
<xsl:template match="/">
<xsl:variable name="result" select="myns:my-func(./*)" />
<xsl:for-each select="$result">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
root = etree.XML('<root></root>')
doc = etree.ElementTree(root)
transform = etree.XSLT(etree.XML(xslt))
res = transform(doc)
root=etree.XML(“”)
doc=etree.ElementTree(根)
transform=etree.XSLT(etree.XML(XSLT))
res=转换(doc)
有关完整的工作示例,请参见此。您的问题是什么?您想知道如何从XML访问Python函数吗?或者,您是否已经将Python链接到XSLT处理器,并且它提供了与您需要的不同的结果?这些结果是什么?您对tehm的期望是什么?您使用的是哪种XSLT处理器?我的答案中哪一部分不适合您?如果我提供一个像pastebin这样的链接,并提供一个完整的工作示例,会有帮助吗?@JamesHolderness如果你能提供一个非常好的工作示例的话!我个人尝试过你的方法,但它对我不起作用,这导致我尝试创建“智能字符串”对象和其他不起作用的解决方案。不管怎样,我已经给了你奖金,我会用一个有效的例子来接受你的回答。谢谢@我已经在我的答案中添加了一个pastebin链接。另外,如果有什么不同,我正在Python 2.6和lxml 3.2.1上测试。我正在使用Python 2.7.3和lxml 3.2.1,运行pastebin代码,并得到一个错误:
xsltaplyError:未能计算变量“result”的表达式。
@pluggd我刚刚从(Windows x86 MSI安装程序)完成了Python 2.7.3的干净安装和lxml 3.2.1(Windows 32位安装程序-lxml-3.2.1.win32-py2.7.exe),我的示例对我来说仍然很好。这可能是操作系统的问题吗?你在Linux上吗?不管是哪种方式,重新安装python和lxml都是值得的。@我刚想到,如果您单独安装了,您使用的libxml或libxslt版本也可能有问题。@pluggd看一下,他们对您需要的libxml和libxslt版本非常挑剔。建议您使用libxml2.7.8或更高版本和libxslt 1.1.26或更高版本。