【问题标题】:add element in a existing xml file python在现有的xml文件python中添加元素
【发布时间】:2016-04-05 13:58:00
【问题描述】:

我有一个现有的 xml 文件如下:

<vehicleTravelTimeMeasurements>
        <vehicleTravelTimeMeasurement name="ckkkkkkkkkk" no="2">
            <start link="1" pos="3.864983"/>
            <end link="3" pos="23.275375"/>
        </vehicleTravelTimeMeasurement>
        <vehicleTravelTimeMeasurement name="" no="3">
            <start link="1" pos="3.864983"/>
            <end link="2" pos="13.275375"/>
        </vehicleTravelTimeMeasurement>
</vehicleTravelTimeMeasurements>

我正在尝试使用 xml.etree.cElementTree 构造与上图相同的格式,并将它们正确添加到 xml 中:

new = ET.Element("vehicleTravelTimeMeasurement", name = "kkk", no = "4")
newsub1 =  ET.Element("start", link = "1", pos="3.88888")
newsub2 = ET.Element("end",link = "3", pos = "3.88888")

有人可以帮我解决这个问题吗?

提前谢谢你!

【问题讨论】:

  • 使用new.append(newsub1)

标签: python xml celementtree


【解决方案1】:

您想使用SubElement 并将startend 元素添加到vehicleTravelTimeMeasurement 元素。然后在位置 2 插入新创建的元素,因为 0 和 1 已经被占用了。

import xml.etree.ElementTree as ET

def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

xml = '''<vehicleTravelTimeMeasurements>
        <vehicleTravelTimeMeasurement name="ckkkkkkkkkk" no="2">
            <start link="1" pos="3.864983"/>
            <end link="3" pos="23.275375"/>
        </vehicleTravelTimeMeasurement>
        <vehicleTravelTimeMeasurement name="" no="3">
            <start link="1" pos="3.864983"/>
            <end link="2" pos="13.275375"/>
        </vehicleTravelTimeMeasurement>
</vehicleTravelTimeMeasurements>'''

root = ET.fromstring(xml)
new = ET.Element("vehicleTravelTimeMeasurement", name = "kkk", no = "4")
newsub1 = ET.SubElement(new, "start", link = "1", pos="3.88888")
newsub2 = ET.SubElement(new, "end",link = "3", pos = "3.88888")
root.insert(2, new)
indent(root)
with open('test.xml', 'w') as f:
    f.write(ET.tostring(root))

【讨论】:

  • 是的。你说得对。他们是一样的。但我的问题是当我以 xml 格式打开文件时。新添加的元素未显示为原始 [0] 或 [1] 元素的结构。
  • @Condo_programmer 我的最新编辑现在写入文件
  • 非常感谢!没关系。这是关于记事本++的问题。问题解决了
【解决方案2】:

短版/更新和编辑:

您唯一需要做的就是 (A) 将 newsub1newsub2 添加到 new。 (B) 将new 添加到root

root = ET.fromstring(xml)  # or whichever way you're getting `root`
# these 3 lines form your code:
new = ET.Element('vehicleTravelTimeMeasurement', name="kkk", no="4")
newsub1 = ET.Element('start', link='1', pos='3.88888')
newsub2 = ET.Element('end', link='3', pos='3.88888')
# the next steps to add
new.append(newsub1)
new.append(newsub2)
root.append(new)

请注意,(A) & (B) 可以按任何顺序完成,并且可以缩短,如下所示:

>>> root = ET.fromstring(xml)
>>> new = ET.Element('vehicleTravelTimeMeasurement', name="kkk", no="4")
>>> root.append(new)  # note that I've immediately added `new`
>>> ET.SubElement(new, 'start', link='1', pos='3.88888')
<Element 'start' at 0x24707b8>
>>> ET.SubElement(new, 'end', link='3', pos='3.88888')
<Element 'end' at 0x24ea978>
>>> # there's no need to store the subelements in `newsub1` and
... # `newsub2` if you don't need to do anything with them
...
>>> indent(root)
>>> print ET.tostring(root)
<vehicleTravelTimeMeasurements>
  <vehicleTravelTimeMeasurement name="ckkkkkkkkkk" no="2">
    <start link="1" pos="3.864983" />
    <end link="3" pos="23.275375" />
  </vehicleTravelTimeMeasurement>
  <vehicleTravelTimeMeasurement name="" no="3">
    <start link="1" pos="3.864983" />
    <end link="2" pos="13.275375" />
  </vehicleTravelTimeMeasurement>
  <vehicleTravelTimeMeasurement name="kkk" no="4">
    <start link="1" pos="3.88888" />
    <end link="3" pos="3.88888" />
  </vehicleTravelTimeMeasurement>
</vehicleTravelTimeMeasurements>

注意事项:

  1. 我在创建后将new 添加到root
  2. 使用append 而不是insert 如果你知道你总是在追加,而不是需要在你的原始xml 中跟踪no
    • 除非您无论如何都需要阅读它来计算下一个“no”属性
  3. ET.SubElement(new) 更新 new(和 root),即使 new 已被附加。
  4. 如果您不需要对子元素进行任何操作,则无需将子元素存储在newsub1newsub2 中。
    • 第一种方法(如您的方法)创建元素,然后将它们添加到 root 或 new。
    • 第二种方法使用ET.SubElement(new, ...) 将元素添加到其父级。
  5. function indent is from here,其中quotes this source

Re #4.2 上面,也可以这样做:

root = ET.fromstring(xml)
new = ET.SubElement(root, 'vehicleTravelTimeMeasurement', name="kkk", no="4")
# `new` is already created as a subelement of `root` and appended
ET.SubElement(new, 'start', link='1', pos='3.88888')
ET.SubElement(new, 'end', link='3', pos='3.88888')

来自Subelement docs

此函数创建一个元素实例,并将其附加到现有元素。

(强调我的)

【讨论】:

  • 您好,谢谢您的回答。你能说得更具体一点吗?
  • 没有add_element,我在想ET.SubElement(&lt;parent&gt;, ...)。所以我的那部分答案是完全错误的。此外,已编辑答案中的最后一个代码 sn-p 是您需要进行的最小更改以执行您想要的操作。 :-)
猜你喜欢
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 2011-09-03
相关资源
最近更新 更多