Select XML 文件中的某些行 Python

Select some rows from a XML file with Python

我有一个 XML 想要导出一些行,基于属性 1 的内容。

我的文件是这样的:

<Root>
  <First_Level_Node>
    <Element_Name>
      <attribute1>1</attribute1>
      <attribute2>2</attribute2>
      <attribute3>3</attribute3>
      <attribute4>4</attribute4>
      <attribute5>5</attribute5>
      <attribute6>6</attribute6>
    </Element_Name>
    <Element_Name>
      <attribute1>41</attribute1>
      <attribute2></attribute2>
      <attribute3>NO</attribute3>
      <attribute4>42</attribute4>
      <attribute5>random value</attribute5>
      <attribute6>18th Jun 2014  07:09:18 GMT</attribute6>
    </Element_Name>
    <Element_Name>
      <attribute1>42</attribute1>
      <attribute2></attribute2>
      <attribute3>NO</attribute3>
      <attribute4>42</attribute4>
      <attribute5>random</attribute5>
      <attribute6>23rd Jul 2014  02:47:10 GMT</attribute6>
    </Element_Name>
    <Element_Name>
      <attribute1>43</attribute1>
      <attribute2></attribute2>
      <attribute3>NO</attribute3>
      <attribute4>42</attribute4>
      <attribute5>random</attribute5>
      <attribute6>08th Nov 2014  23:53:31 GMT</attribute6>
    </Element_Name>
  </First_Level_Node>
</Root>

并且根据属性 1 的值,我想从该元素中获取所有行。 例如,我想要属性 1 = 42 或属性 1 = 43,所以输出将类似于:

<Root>
  <First_Level_Node>
    <Element_Name>
      <attribute1>42</attribute1>
      <attribute2></attribute2>
      <attribute3>NO</attribute3>
      <attribute4>42</attribute4>
      <attribute5>random</attribute5>
      <attribute6>23rd Jul 2014  02:47:10 GMT</attribute6>
    </Element_Name>
    <Element_Name>
      <attribute1>43</attribute1>
      <attribute2></attribute2>
      <attribute3>NO</attribute3>
      <attribute4>42</attribute4>
      <attribute5>random</attribute5>
      <attribute6>08th Nov 2014  23:53:31 GMT</attribute6>
    </Element_Name>
  </First_Level_Node>
</Root>

我想为此使用 Python。

我尝试使用 ElementTree,但没有成功。这就是我到目前为止所尝试的

with open("output.xml", 'r') as f3:
        root = ET.parse(f3)

    tree=root.getroot()
    with open("list_xxx", 'r') as f2:
        for line in f2:
            line = line.rstrip()
            print (line)
            #get all subnet nodes containing certain ManagedElementId
            subnet_path = './/*[attribute1="{0}"]'
            subnet_path = subnet_path.format(line)
            for subnet in tree.findall(subnet_path):
                #reconstruct subnet node:
                parent = ET.Element(subnet.tag, attrib=subnet.attrib)
                #path to find all ManagedElement containing certain ManagedElementId
                content_path = ".//*[attribute1='{0}']".format(line)
                print (content_path)

                #append all ManagedElement found to the new subnet:
                for content in subnet.findall(content_path):
                    parent.append(content)
                #print new subnet:
                print (ET.tostring(parent))

并且列表 xxx 具有我要查找的属性 1 的值:

41
42

使用 lxml 和 xpath 应该会更简单:

from lxml import etree

dat = """[your xml snippet above]"""
doc = etree.fromstring(dat)

targets = doc.xpath('//Element_Name[not(attribute1="42" or attribute1="43")]')
#the xpath expression above selects all ElementName nodes which do NOT meet your requirements
for target in targets:
    target.getparent().remove(target) #once an unnecessary element is selected, you go up to the parent and remove the unnecessary element
print(etree.tostring(doc).decode())

输出就是你想要的输出。

您已经预select编辑了具有指定 attribute1 内容(41 和 42)的 Element_Name 元素。不需要第二次重新 select 它们,这会导致 findall().

返回整个 Element_Name 元素

此时您只需要 select 子 attribute1 元素。

因此,如果您更改

content_path = ".//*[attribute1='{0}']".format(line)

 content_path = "attribute1"

您的程序将打印:

41
attribute1
b'<Element_Name><attribute1>41</attribute1>\n      </Element_Name>'
42
attribute1
b'<Element_Name><attribute1>42</attribute1>\n      </Element_Name>'