使用 python 解析来自 xml 的数据 3

parse data from xml using python 3

请找到mwe xml文件(实际文件长81k行,我只展示了一小部分)。

<?xml version="1.0" encoding="ISO-8859-1"?>
<modeling>
  <dos>
    <i name="efermi">     -2.48501882 </i>
    <total>
      <array>
        <dimension dim="1">gridpoints</dimension>
        <dimension dim="2">spin</dimension>
        <field>energy</field>
        <field>total</field>
        <field>integrated</field>
        <set>
          <set comment="spin 1">
            <r>   -55.6029     0.0000     0.0000 </r>
            <r>   -55.3940     0.0000     0.0000 </r>
            <r>   -55.1850     0.0000     0.0000 </r>
            <r>   -54.9761     0.0000     0.0000 </r>
          </set>
          <set comment="spin 2">
            <r>   -55.6029     0.0000     0.0000 </r>
            <r>   -55.3940     0.0000     0.0000 </r>
            <r>   -55.1850     0.0000     0.0000 </r>
            <r>   -54.9761     0.0000     0.0000 </r>
          </set>
        </set>
      </array>
    </total>
    <partial>
      <array>
        <dimension dim="1">gridpoints</dimension>
        <dimension dim="2">spin</dimension>
        <dimension dim="3">ion</dimension>
        <field>energy</field>
        <field>    s</field>
        <field>   py</field>
        <field>   pz</field>
        <field>   px</field>
        <field>  dxy</field>
        <field>  dyz</field>
        <field>  dz2</field>
        <field>  dxz</field>
        <field>x2-y2</field>
        <set>
          <set comment="ion 1">
            <set comment="spin 1">
              <r>   -55.6029     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -55.3940     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -55.1850     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -54.9761     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
            </set>
            <set comment="spin 2">
              <r>   -55.6029     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -55.3940     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -55.1850     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
              <r>   -54.9761     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000     0.0000 </r>
            </set>
          </set>
        </set>
      </array>
    </partial>
  </dos>
</modeling>

下面嵌套了dos标签,spin 1等组件中的值不一定为0。 我已经设法到达 dos 标签,并获得了 efermi 值,但不明白如何分别和有选择地获取集合,以便我可以使用 matplotlib 绘制它。

这是我当前的代码:

#!/usr/bin/env python
import xml.etree.ElementTree as ET

tree = ET.parse("trial.xml")
root = tree.getroot()

for elem in root:
  print(elem.tag)
  if elem.tag == 'dos':
    for x in elem:
      print(x.attrib.get('name'), x.text)

您可以直接使用 https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findall 和 xpath(如:'node_a.node_b.etc.req_node')获取集合,如下面的代码所示...(也可以访问评论文字)

import xml.etree.ElementTree as ET
import pandas as pd
from matplotlib import pyplot as plt

tree = ET.fromstring("test.xml")
root = tree.getroot()


for elem in root.findall('./dos/partial/array/set/set/set'):
    comment = elem.get('comment')
    print(comment)
    data = list()
    for row in elem.findall('r'):
        data.append(list(map(float, row.text.split())))
    df = pd.DataFrame(data)
    print(df)
    df.plot()
    plt.show()