1

我开始lxml在 Python 中使用来处理 XML/XSL 文档,而且总的来说它看起来非常简单。但是,在进行翻译时,我找不到将 XML 片段作为样式表参数传递的方法。

例如,在 PHP 中,可以将DOMDocumentXML 片段作为样式表参数传递,这样就可以在样式表中使用复杂的参数:

$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

4

3 回答 3

1

据我所知,您只能在 lxml 中使用 xpath 表达式(或 etree.XSLT.strparam() 方法的结果,用于带引号的字符串)(目前无论如何)。

但是,因为您可以使用 xpath 表达式,这意味着您可以通过使用返回相关元素的自定义 xpath 扩展函数来“解决”问题。另一种方法是使用标准的 xpath document() 函数,并使用自定义解析器

于 2009-11-18T16:56:46.623 回答
1

您可以使用 python 扩展函数将 etree.XML 文档返回到 xslt。这是最简单的例子。它注册了一个全局命名空间(uri:params),将一个函数与该命名空间中的“params”方法关联起来。样式表使用它来达到扩展功能。不要忘记样式表中的 xmlns:ptest 声明。

嗯,看起来我将不得不在这段代码中放入 html 实体来表示 < 符号。我也把它放在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()
于 2010-01-03T01:51:30.383 回答
0

我相信您可以使用lxml.etree.XSLT来执行您要查找的内容。可以在使用 lxml 记录 XPath 和 XSLT页面的XSLT 部分中找到很好的示例。

于 2009-11-18T21:16:09.117 回答