更改lxml中的元素命名空间



使用lxml,我不知道如何正确删除现有元素的名称空间并设置新的名称空间。

例如,我正在解析这个最小的xml文件:

<myroot xmlns="http://myxml.com/somevalue">
<child1>blabla</child1>
<child2>blablabla</child2>
</myroot>

我希望它变成:

<myroot xmlns="http://myxml.com/newvalue">
<child1>blabla/child1>
<child2>blablabla</child2>
</myroot>

lxml:

from lxml import etree as ET
tree = ET.parse('myfile.xml')
root= tree.getroot()

如果我检查root:

In [7]: root
Out[7]: <Element {http://myxml.com/somevalue}myroot at 0x7f6e13832588>
In [8]: root.nsmap
Out[8]: {None: 'http://myxml.com/somevalue'}
In [11]: root.tag
Out[11]: '{http://myxml.com/somevalue}myroot'

理想情况下,我希望最终得到:

In [8]: root.nsmap
Out[8]: {None: 'http://myxml.com/newvalue'}
In [11]: root.tag
Out[11]: '{http://myxml.com/newvalue}myroot'

至于标签,这只是设置正确字符串的问题。nsmap怎么样?

我同意mzjn和Parfait;我会使用XSLT来更改名称空间。

通过将新旧名称空间作为参数传入,可以使XSLT相当可重用。

示例。。。

XML输入(Input.XML(

<myroot xmlns="http://myxml.com/somevalue">
<child1>blabla</child1>
<child2>blablabla</child2>
</myroot>

XSLT 1.0(test.xsl(

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="orig_namespace"/>
<xsl:param name="new_namespace"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:choose>
<xsl:when test="namespace-uri()=$orig_namespace">
<xsl:element name="{name()}" namespace="{$new_namespace}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Python

from lxml import etree
tree = etree.parse("input.xml")
xslt = etree.parse("test.xsl")
orig_namespace = "http://myxml.com/somevalue"
new_namespace = "http://myxml.com/newvalue"
new_tree = tree.xslt(xslt, orig_namespace=f"'{orig_namespace}'",
new_namespace=f"'{new_namespace}'")
print(etree.tostring(new_tree, pretty_print=True).decode("utf-8"))

输出

<myroot xmlns="http://myxml.com/newvalue">
<child1>blabla</child1>
<child2>blablabla</child2>
</myroot>

此外,如果使用以下输入(使用名称空间前缀(。。。

<ns1:myroot xmlns:ns1="http://myxml.com/somevalue">
<ns1:child1>blabla</ns1:child1>
<ns1:child2>blablabla</ns1:child2>
</ns1:myroot>

你得到这个输出。。。

<ns1:myroot xmlns:ns1="http://myxml.com/newvalue">
<ns1:child1>blabla</ns1:child1>
<ns1:child2>blablabla</ns1:child2>
</ns1:myroot>

请参阅https://lxml.de/xpathxslt.html有关在lxml中使用XSLT的更多信息。

相关内容

  • 没有找到相关文章

最新更新