【问题标题】:Insert XML Value/Element with Python使用 Python 插入 XML 值/元素
【发布时间】:2015-07-29 16:45:28
【问题描述】:

我一直在寻找将元素/值添加到当前 XML 文件的解决方案。因此,假设我有以下 XML 文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Node>
        <Name>Sprinkler</Name>
        <Type>Blah</Type>
        <Prob>0.82</Prob>
    </Node>
    <Node>
        <Name>Rain</Name>
        <Type>Bleh</Type>
        <Prob>0.23</Prob>
    </Node>
    <Node>
        <Name>Cloudy</Name>
        <Type>Bluh</Type>
        <Prob>0.71</Prob>
    </Node>
</Root>

现在,我的目标是,给定一个 CSV 文件,我想为每个节点添加新元素和值。假设我的 CSV 包含这样的内容:

Cloudy,Or,Sprinkler,Rain
Sprinkler,And,Rain
Rain,Or,Sprinkler,Cloudy

我能够毫无问题地读取 CSV,我的问题是添加新元素“Parent0”和“Parent1”(如果有),因此输出如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Node>
        <Name>Sprinkler</Name>
        <Type>Blah</Type>
        <Prob>0.82</Prob>
        <Gate>And</Gate>
        <Parent0>Rain</Parent0>
    </Node>
    <Node>
        <Name>Rain</Name>
        <Type>Bleh</Type>
        <Prob>0.23</Prob>
        <Gate>Or</Gate>
        <Parent0>Sprinkler</Parent0>
        <Parent1>Cloudy</Parent1>
    </Node>
    <Node>
        <Name>Cloudy</Name>
        <Type>Bluh</Type>
        <Prob>0.71</Prob>
        <Gate>Or</Gate>
        <Parent0>Sprinkler</Parent0>
        <Parent1>Rain</Parent1>
    </Node>
</Root>

到目前为止,我已经用 Python 编写了以下内容:

import xml.etree.ElementTree as ET

xml = ET.parse('XML.xml')
for row in xml.iterfind('Node'):
    i = 1
    for item in csvFile:
        row.append('<Gate>'+item[1]+'</Gate>\n')
        if i != 1:
            for x in xrange(0, len(item):
                if row.findtext('Name') == item[x]:
                    row.append('<Parent0>'+item[x]+'</Parent0>\n')
        else:
            i = 0

在我的代码中,它现在将全部转到 Parent0,但我想看看如何在不删除所有内容的情况下进行追加?我听说过 lxml 和 minidom,但不确定它们是如何工作的。如果我能够使用 xml.etree.ElementTree 做到这一点,那就太棒了。

【问题讨论】:

  • 原谅我,但当你真正指的是元素时,你在标题和帖子中错误地提到了属性:&lt;element attribute = "attributevalue"&gt;elementvalue&lt;/element&gt;。您正在尝试添加新元素 GateParent0Parent1 以及值而不是属性和值。抱歉,这似乎很挑剔,但 Python 代码在两者之间略有不同。
  • 谢谢,@Parfait。是的,你是对的!我通常对两者都感到困惑。但是,是的,我指的是元素,而不是属性

标签: python xml elementtree


【解决方案1】:

一种简单的方法是使用ElementTree.SubElement() 创建元素,它会自动将这些元素添加到作为参数传入的父节点的末尾。

示例/演示 -

>>> import xml.etree.ElementTree as ET
>>> import csv
>>> with open('test.csv','r') as f:
...     cfiles = list(csv.reader(f))
...
>>> xml = ET.parse('XML.xml')
>>> for row in xml.iterfind('.//Node'):
...     name = row.find('./Name').text
...     for i in cfiles:
...         if i[0] == name:
...             j = 1
...             while j < len(i):
...                 if j == 1:
...                     g = ET.SubElement(row,'Gate')
...                     g.text = i[j]
...                 elif j == 2:
...                     g = ET.SubElement(row,'Parent0')
...                     g.text = i[j]
...                 elif j == 3:
...                     g = ET.SubElement(row,'Parent1')
...                     g.text = i[j]
...                 j += 1
...
>>> print(ET.tostring(xml.getroot()).decode())
<Root>
    <Node>
        <Name>Sprinkler</Name>
        <Type>Blah</Type>
        <Prob>0.82</Prob>
    <Gate>And</Gate><Parent0>Rain</Parent0></Node>
    <Node>
        <Name>Rain</Name>
        <Type>Bleh</Type>
        <Prob>0.23</Prob>
    <Gate>Or</Gate><Parent0>Sprinkler</Parent0><Parent1>Cloudy</Parent1></Node>
    <Node>
        <Name>Cloudy</Name>
        <Type>Bluh</Type>
        <Prob>0.71</Prob>
    <Gate>Or</Gate><Parent0>Sprinkler</Parent0><Parent1>Rain</Parent1></Node>
</Root>

在上面,cfiles 是我之前从 csv 文件创建的列表。


要将 xml 写入新文档,请执行 -

with open('newxml.xml','w') as of:
    of.write(ET.tostring(xml.getroot()).decode())

【讨论】:

  • 非常感谢@Anand!我实际上是在寻找 SubElement 功能,只是找不到。我认为它是出于某种原因附加的。这很容易!再次感谢
  • 您将如何将其保存到 XML 文档中?我尝试获取您编写的打印语句并将其写入新文档,但它不起作用。有办法吗?
猜你喜欢
  • 1970-01-01
  • 2012-10-03
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
相关资源
最近更新 更多