我开始在Python中使用lxml
来处理XML / XSL文档,而且一般来说它看起来非常简单。但是,在进行翻译时,我无法找到将XML片段作为样式表参数传递的方法。
例如,在PHP中,可以将DOMDocument
XML片段作为样式表参数传递,以便在样式表中可以使用复杂的参数:
$xml = new DOMDocument();
$xml->loadXML('<root><node/></root>');
$xsl = new DOMDocument();
$xsl->loadXML('<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes"
indent="yes" media-type="text/html" />
<xsl:param name="a" />
<xsl:template match="/">
<html>
<body>
<xsl:value-of select="$a/foo/bar/text()" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>');
$fragment = new DOMDocument();
$fragment->loadXML('<foo><bar>baz</bar></foo>');
$proc = new XSLTProcessor;
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsl);
$param_ns = '';
$param_name = 'a';
$proc->setParameter($param_ns, $param_name, $fragment->documentElement);
这将导致:
<html>
<body>
baz
</body>
</html>
如何使用lxml
完成此操作?
答案 0 :(得分:1)
据我所知,你只能在lxml中使用xpath表达式(或带引号的字符串的etree.XSLT.strparam()方法的结果)(目前无论如何)。
但是,因为您可以使用xpath表达式,这意味着您可以使用返回相关元素的custom xpath extension function来“解决”。另一种方法是使用标准的xpath document()函数,并使用custom resolver
答案 1 :(得分:0)
我相信您所寻找的内容可以使用lxml.etree.XSLT来执行。可以在记录XSLT section的页面上的XPath and XSLT with lxml找到好的示例。
答案 2 :(得分:0)
您可以使用python扩展函数将etree.XML文档返回给xslt。这是最基本的例子。它注册一个全局命名空间(uri:params),将一个函数与该命名空间中的“params”方法相关联。样式表使用它来达到扩展功能。不要忘记样式表中的xmlns:ptest声明。
嗯,看起来我将不得不放入html实体来表示&lt;此代码中的符号。我也把它放在http://bkc.pastebin.com/f67461ccc 中
from lxml import etree
stylesheet = etree.XML("""
<xsl:stylesheet version="1.0"
xmlns:ptest="uri:params"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="params" select="ptest:params()" />
<xsl:template match="/">
<name_is><xsl:value-of select="$params/name" /></name_is>
</xsl:template>
</xsl:stylesheet>
""")
def params(context):
# this is the extension function, it returns
# a etree.XML document
return etree.XML(
"""<params>
<name>fred
</params>"""
)
def test():
"""test passing document to xslt via python extension function
>>> test()
<?xml version="1.0"?>
<name_is xmlns:ptest="uri:params">fred
<BLANKLINE>
"""
ns = etree.FunctionNamespace('uri:params') # register global namespace
ns['params'] = params # define function in new global namespace
transform = etree.XSLT(stylesheet)
print str(transform(etree.XML("""<source />""")))
if __name__ == "__main__":
import doctest
doctest.testmod()