Python 用lxml作为样式表参数传递XML片段?
我开始在Python中使用Python 用lxml作为样式表参数传递XML片段?,python,xml,xslt,lxml,Python,Xml,Xslt,Lxml,我开始在Python中使用lxml来处理XML/XSL文档,一般来说,这看起来非常简单。但是,在进行翻译时,我无法找到将XML片段作为样式表参数传递的方法 例如,在PHP中,可以将DOMDocumentXML片段作为样式表参数传递,这样就可以在样式表中提供复杂的参数: $xml = new DOMDocument(); $xml->loadXML('<root><node/></root>'); $xsl = new DOMDocument(); $x
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);
$xml=newDOMDocument();
$xml->loadXML(“”);
$xsl=newdomdocument();
$xsl->loadXML('
');
$fragment=新的DOMDocument();
$fragment->loadXML('baz');
$proc=新的XSLTProcessor;
$proc->RegisterHPFunctions();
$proc->importStyleSheet($xsl);
$param_ns='';
$param_name='a';
$proc->setParameter($param_ns,$param_name,$fragment->documentElement);
这将导致:
<html>
<body>
baz
</body>
</html>
巴兹
如何使用
lxml
实现这一点?据我所知,您只能在lxml中使用xpath表达式(或者对带引号的字符串使用etree.XSLT.strparam()方法的结果)(无论如何,目前是这样)
但是,由于可以使用xpath表达式,这意味着您可以通过使用返回相关元素的。另一种方法是使用标准的xpath document()函数,并使用。很好的例子可以在页面上的文档中找到。您可以使用python扩展函数将etree.XML文档返回到xslt。下面是最简单的例子。它注册一个全局名称空间(uri:params),将函数与该名称空间中的“params”方法相关联。样式表使用它来访问扩展函数。不要忘记样式表中的xmlns:ptest声明 嗯,看起来我必须在代码中放入html实体来表示<符号。我也把它放进去了
从lxml导入etree
样式表=etree.XML(“”)
""")
def参数(上下文):
#这是扩展函数,它返回
#etree.XML文档
返回etree.XML(
"""
弗雷德
"""
)
def test():
“”“测试通过python扩展函数将文档传递给xslt
>>>测试()
弗雷德
"""
ns=etree.FunctionNamespace('uri:params')#注册全局命名空间
ns['params']=params#在新的全局命名空间中定义函数
transform=etree.XSLT(样式表)
打印str(转换(etree.XML(“”))
如果名称=“\uuuuu main\uuuuuuuu”:
进口医生测试
doctest.testmod()
谢谢。你能编辑你的帖子并用自定义解析器更改页面链接吗?我在发布后注意到了自定义xpath函数,并得出了相同的结论,但document()
方法可能更有用。这个答案很特别,因为@Steven的分数太少,无法发布多个链接。他现在有大约12千分。漫长的道路。
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()