首页 > 解决方案 > 将 Python XML ElementTree 输出写入 CSV

问题描述

TL;DR 我现在可以在 CSV 中输出我想要的信息,但我只是一遍又一遍地重复最后一个 XML 文件的数据。

这是脚本的最新版本:

import csv
import glob
import xml.etree.ElementTree as ET
filenames = glob.glob("..\Lib\macros\*.xml")

for filename in filenames:

  with open(filename, 'r') as content:
    element = ET.parse(content)
    root = element.getroot()
    print(root.attrib, filename)
  e = element.findall('commands/MatrixSwitch/')
  for i in e:
    print (i.tag, i.text)


    with open('results.csv', 'w', newline='') as file:
        for filename in filenames:
            writer = csv.writer(file)
            writer.writerow([root.attrib, filename])
            for i in e:
                writer.writerow([i.tag, i.text])

假设我有 10 个 XML 文件,我在 CSV 中获得了 10 次与 XML“文件 10”相关的输出,而不是 XML“文件 1-9”的任何内容......确定它很简单吗?

==================================================== ========================

我编写了一个小脚本,它提取一个 XML 文件文件夹,搜索特定元素,然后调用一些数据。然后将其打印到控制台并写入 CSV,除非我无法正确格式化我的 CSV。

这是我到目前为止的地方:

import csv
import glob
import xml.etree.ElementTree as ET
filenames = glob.glob("..\Lib\macros\*.xml")

for filename in filenames:

  with open(filename, 'r') as content:
    element = ET.parse(content)
    root = element.getroot()
    print(root.attrib, filename)
  e = element.findall('commands/MatrixSwitch/')
  for i in e:
    print (i.tag, i.text)
  with open('results.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow([root.attrib, filename])

我正在寻找以下数据:

我只对在 XML 中引用“矩阵开关”感兴趣。有时可能只有一个监视器 ID 和一个摄像机 ID,有时可能会有更多,因此脚本需要循环并获取“Matrix Switch”元素中的所有 ID。到目前为止,这似乎有效。

典型的 XML 结构如下所示:

<macro name="NAME OF THE MACRO IS SHOWN HERE">
<execution>
<delay>0</delay>
</execution>
<parameters/>
<commands>
<MatrixSwitch>
<camera>1530</camera>
<monitor>1020</monitor>
</MatrixSwitch>
<MatrixSwitch>
<camera>1531</camera>
<monitor>1001</monitor>
</MatrixSwitch>
</commands>
</macro>

或者像这样:

<macro name="ANOTHER NAME GOES HERE">
<execution>
<delay>0</delay>
</execution>
<parameters/>
<commands>
<MatrixSwitch>
<camera>201</camera>
<monitor>17</monitor>
</MatrixSwitch>
<MatrixSwitch>
<camera>206</camera>
<monitor>18</monitor>
</MatrixSwitch>
<MatrixSwitch>
<camera>202</camera>
<monitor>19</monitor>
</MatrixSwitch>
<MatrixSwitch>
<camera>207</camera>
<monitor>20</monitor>
</MatrixSwitch>
</commands>
</macro>

我当前的 results.csv 仅设置为输出名称和文件名。这可行,但我不确定我需要在哪里将“writer”命令添加到处理 Monitor ID 和 Camera ID 的循环中。

我希望我的 CSV 显示:名称、文件名、监视器 A、摄像头 A、监视器 B、摄像头 B、监视器 C、摄像头 C、监视器 D、摄像头 D 等.....

任何指针都非常感谢!

代码现在略有改动:

import csv
import glob
import xml.etree.ElementTree as ET
filenames = glob.glob("..\Lib\macros\*.xml")

for filename in filenames:

  with open(filename, 'r') as content:
    element = ET.parse(content)
    root = element.getroot()
    print(root.attrib, filename)
  e = element.findall('commands/MatrixSwitch/')
  for i in e:
    print (i.tag, i.text)
    with open('results.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([root.attrib, filename])
        for i in e:
           writer.writerow([i.tag, i.text])

CSV 中的输出如下:

https://imgur.com/a/SrPrgjm

标签: pythoncsvelementtree

解决方案


只需添加一个调用 writerow 的循环:

...
with open('results.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow([root.attrib, filename])
    for i in e:
        writer.writerow([i.tag, i.text])

推荐阅读