我有两个XML文件。它们非常相似。
第一个:
<a>
<b />
...
<c e='very important'>
<d e='bla' />
<d e='bla' />
</c>
</a>
和第二个:
<a>
<f />
...
<d e='some' />
<d e='values' />
</a>
我必须修改第二个XML,将第一个XML中的 c 标记复制到第二个XML中并用它包装所有 d 兄弟。我想得到类似的东西:
<a>
<f />
...
<c e='very important'>
<d e='some' />
<d e='values' />
</c>
</a>
怎么做?
编辑
我的尝试很少:
import xml.etree.ElementTree as ET
f_tree = ET.parse(f_file)
s_tree = ET.parse(s_file)
f_root = f_tree.getroot()
s_root = s_tree.getroot()
one_c = f_root.find('c')
all_d = s_root.findall('d')
for child in one_c:
one_c.remove(child)
for the_d in all_d:
one_c.append(the_d)
答案 0 :(得分:0)
虽然可能存在内置xml.etree
的解决方案,可能涉及循环逻辑或复制树,但请考虑使用Python的第三方模块lxml
的XSLT 1.0解决方案。 / p>
作为背景,XSL系列的一部分包含XPath,XSLT是一种用于转换XML文档的专用语言。 XSLT维护document()
函数,允许您跨文档创建相对于当前XML源的XPath表达式。
下面假设所有XML和XSL文档都在同一目录中。另请注意,如图所示,XSLT脚本是格式良好的XML文件,可以像任何其他XML一样进行解析。
XSLT 脚本(另存为.xsl或.xslt文件)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<xsl:copy-of select="*[local-name()!='d']"/>
<c>
<xsl:copy-of select="document('f_file.xml')/a/c/@*"/>
<xsl:copy-of select="d"/>
</c>
</xsl:copy>
</xsl:template>
</xsl:transform>
Python 脚本
import os
import lxml.etree as ET
f_tree = ET.parse('f_file.xml')
s_tree = ET.parse('s_file.xml')
xslt = ET.parse('XSLT_Script.xsl')
transform = ET.XSLT(xslt)
newdom = transform(s_tree)
# PRINT TO SCREEN
print(newdom)
# <?xml version="1.0"?>
# <a>
# <f/>
# <other/>
# <c e="very important">
# <d e="some"/>
# <d e="values"/>
# </c>
# </a>
# OUTPUT TO FILE
with open('Output.xml', 'wb') as f:
f.write(newdom)