我正在使用lxml来修改xml。在下面的代码中,我想删除所有"标题"的子项。元素并将子文本分配给其父文件。
最初
<heading><whateverchildvalue>TEXTIWANT</whateverchildvalue></heading>
到
<heading>TEXTIWANT</heading>)
我尝试使用循环,但是当我调用node.remove(attr_children [0])时,它跳出循环并继续下一次调用&#34; ET.tostring(已解析)& #34; (?)并没有修改第二个&#34;标题&#34;。要理解这一点,请删除&#34; node.remove(attr_children [0])&#34;并重新运行以下代码并比较之前打印的版本。我在这里做错了什么,以便它可以做一个适当的循环,并将子文本分配给&#34;标题&#34;所有人的父母&#34;标题&#34; xml字符串中的元素?
xml_string="""
<note>
<to>Tove</to>
<mybigheader>
<heading><deleteme>Jani</deleteme></heading>
<heading><wantkey>Reminder</wantkey></heading>
</mybigheader>
<body>Don't forget me this weekend!</body>
</note>
"""
def modif_xml(xml_string):
parsed = ET.fromstring(xml_string)
for node in parsed.iter():
print "node is ", node
if "heading" in node.tag:
attr_children = node.getchildren()
for i in attr_children:
child_tag = i.tag
child_value = i.text
node.remove(attr_children[0])
node.text = child_value
my_xml = ET.tostring(parsed)
root = ET.XML(my_xml)
print ET.tostring(root, pretty_print=True)
modif_xml(xml_string)
答案 0 :(得分:1)
考虑http://prntscr.com/f5o8fc,这是用于转换XML文件的特殊用途声明性语言。 Python的lxml模块可以运行XSLT 1.0脚本。虽然这看起来有些过分,但您可以避免任何for
循环和if
逻辑。此外,XSLT脚本是 XML文件,可以像任何XML一样处理:从字符串或文件解析。
特别是在下面运行XSLT(按原样复制文档),然后通过调用apply-templates
而不是xsl:copy
重新编写标题子项的模板(这样可以避免当前节点):
import lxml.etree as et
xml_string="""
<note>
<to>Tove</to>
<mybigheader>
<heading><deleteme>Jani</deleteme></heading>
<heading><wantkey>Reminder</wantkey></heading>
</mybigheader>
<body>Don't forget me this weekend!</body>
</note>
"""
dom = et.fromstring(xml_string)
xsl_string='''
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="heading/*">
<xsl:apply-templates />
</xsl:template>
</xsl:transform>
'''
xslt = et.fromstring(xsl_string)
transform = et.XSLT(xslt)
newdom = transform(dom)
print(newdom)
# <?xml version="1.0"?>
# <note>
# <to>Tove</to>
# <mybigheader>
# <heading>Jani</heading>
# <heading>Reminder</heading>
# </mybigheader>
# <body>Don't forget me this weekend!</body>
# </note>