如何在ElementTree中替换子元素

时间:2012-01-13 03:15:46

标签: python elementtree

我希望根据某些条件将子元素从一个树替换为另一个树。我可以用理解来做到这一点吗?但是我们如何替换ElementTree中的元素?

3 个答案:

答案 0 :(得分:2)

与DOM不同,etree没有明确的多文档功能。但是,您应该能够将元素从一个文档自由移动到另一个文档。您可能需要在执行此操作后致电_setroot

通过调用insert然后调用remove,您可以替换文档中的节点。

答案 1 :(得分:2)

您无法替换ElementTree中只能使用Element的元素。

即使您拨打ElementTree.find(),它也只是getroot().find()的快捷方式。

所以你真的需要:

  • 提取父元素
  • 在该父元素上使用理解(或任何你喜欢的东西)

如果您的目标是根子元素(只需调用getroot()),则可以轻松提取父元素,否则您将不得不找到它。

答案 2 :(得分:1)

我是python的新手,但我发现了一种狡猾的方法:

输入文件input1.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <import ref="input2.xml" />
    <name awesome="true">Chuck</name>
</root>

输入文件input2.xml

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar>blah blah</bar>
</foo>

Python代码:(注意,凌乱和hacky)

import os
import xml.etree.ElementTree as ElementTree

def getElementTree(xmlFile):
    print "-- Processing file: '%s' in: '%s'" %(xmlFile, os.getcwd())
    xmlFH = open(xmlFile, 'r')
    xmlStr = xmlFH.read()
    et = ElementTree.fromstring(xmlStr)
    parent_map = dict((c, p) for p in et.getiterator() for c in p)
    # ref: https://stackoverflow.com/questions/2170610/access-elementtree-node-parent-node/2170994
    importList = et.findall('.//import[@ref]')
    for importPlaceholder in importList:
        old_dir = os.getcwd()
        new_dir = os.path.dirname(importPlaceholder.attrib['ref'])
        shallPushd = os.path.exists(new_dir)
        if shallPushd:
            print "  pushd: %s" %(new_dir)
            os.chdir(new_dir) # pushd (for relative linking)
        # Recursing to import element from file reference
        importedElement = getElementTree(os.path.basename(importPlaceholder.attrib['ref']))

        # element replacement
        parent = parent_map[importPlaceholder]
        index = parent._children.index(importPlaceholder)
        parent._children[index] = importedElement

        if shallPushd:
            print "  popd: %s" %(old_dir)
            os.chdir(old_dir) # popd

    return et

xmlET = getElementTree("input1.xml")
print ElementTree.tostring(xmlET)

给出输出:

-- Processing file: 'input1.xml' in: 'C:\temp\testing'
-- Processing file: 'input2.xml' in: 'C:\temp\testing'
<root>
    <foo>
    <bar>blah blah</bar>
</foo><name awesome="true">Chuck</name>
</root>

这是从以下信息得出的结论: