【问题标题】:How to parse XML data into a list in Python如何在 Python 中将 XML 数据解析为列表
【发布时间】:2019-10-12 20:44:56
【问题描述】:

我正在尝试获取 API 调用响应并将 XML 数据解析为列表,但我正在努力处理多个子/父关系。

我希望导出一个新的 XML 文件,该文件将排列每个工作 ID 和跟踪号,然后我可以将其导入 Excel。


这是我目前所拥有的

源 XML 文件如下所示:

<project>
   <name>October 2019</name>
   <jobs>
      <job>
      <id>5654206</id>
      <tracking>
         <mailPiece>
             <barCode>00270200802095682022</barCode>
             <address>Accounts Payable,1661 Knott Ave,La Mirada,CA,90638</address>
             <status>En Route</status>
             <dateTime>2019-10-12 00:04:21.0</dateTime>
             <statusLocation>PONTIAC,MI</statusLocation>
        </mailPiece>
     </tracking>...

代码:

import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, SubElement

tree = ET.parse('mailings.xml')
root = tree.getroot()
print(root.tag)

for x in root[1].findall('job'):
    id=x.find('id').text
    tracking=x.find('tracking').text
    print(root[1].tag,id,tracking)

脚本当前返回以下内容:

jobs 5654206 None
jobs 5654203 None

【问题讨论】:

  • 对于您的 xml sn-p,您是否正在寻找像 id: ['5654206'] barCode: ['00270200802095682022'] 这样的输出?
  • 您能添加一个您想要的 xml 输出示例吗?

标签: python python-3.x xml-parsing elementtree


【解决方案1】:

调试是你的朋友...

我正在为多重子女/父母关系而苦苦挣扎。

自行解决此问题的正确方法是使用调试器。例如,使用 VS Code,在应用断点并使用调试器运行脚本后,它将在断点处停止,我可以检查内存中的所有变量,并在调试控制台上运行命令,就像它们在我的脚本中一样.变量窗口输出如下所示:

有多种方法可以在命令行中执行此操作,或者使用 iPython 等 REPL 等,但我发现在 VS Code 等现代 IDE 环境中使用调试PyCharm 绝对是要走的路。他们的调试器无需在各处使用打印语句来测试您的代码、重写代码以公开更多必须打印到控制台的变量等。

调试器允许您在代码执行的任何时候以快照的形式查看所有变量,以及 Python 解释器如何查看它们。你可以:

  • 逐行浏览您的代码,并在窗口中实时观察变量变化
  • 设置一个单独的监视窗口,只包含您关心的变量
  • 并设置仅在变量设置为特定值等情况下才会发生的断点。

使用 XML find 方法的子层次结构

在我单步执行您的代码时检查变量,find() 方法似乎在所有级别的元素中遍历子项,而不仅仅是在顶层。当您使用x.find('tracking') 时,它会直接找到mailPiece 节点。如果您打印tag 属性,而不是text 属性,您将看到它是'mailPiece'(请参阅上面的调试窗口)。

因此,解决您的问题的一种方法是将每个 mailPiece 元素存储为一个变量,然后使用 find 从中提取您想要的各个属性(即条形码、地址等)。

这里有一些代码可以将所有这些内容整合到列表和字典的组合层次结构中,然后您可以使用它们来构建 Excel 输出。

注意:执行此操作的最有效方法是在读取 xml 时逐行执行此操作,但这对于可读性、可维护性以及如果您需要进行任何后处理更好这需要一次了解多个节点。

import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, SubElement
from types import SimpleNamespace

tree = ET.parse('mailings.xml')
root = tree.getroot()

jobs = []
for job in root[1].findall('job'):
    jobdict = {}
    jobdict['id'] = job.find('id').text
    jobdict['trackingMailPieces'] = []
    for tracking in job.find('tracking'):
        if tracking.tag == 'mailPiece':
            mailPieceDict = {}
            mailPieceDict['barCode'] = tracking.find('barCode').text
            mailPieceDict['address'] = tracking.find('address').text
            mailPieceDict['status'] = tracking.find('status').text
            mailPieceDict['dateTime'] = tracking.find('dateTime').text
            mailPieceDict['statusLocation'] = tracking.find('statusLocation').text
            jobdict['trackingMailPieces'].append(mailPieceDict)
    jobs.append(jobdict)

for job in jobs:
    print('Job ID: {}'.format(job['id']))
    for mp in job['trackingMailPieces']:
        print('  mailPiece:')
        for key, value in mp.items():
            print('    {} = {}'.format(key, value))

结果是:

Job ID: 5654206
  mailPiece:
    barCode = 00270200802095682022
    address = Accounts Payable,1661 Knott Ave,La Mirada,CA,90638
    status = En Route
    dateTime = 2019-10-12 00:04:21.0
    statusLocation = PONTIAC,MI

输出?

我没有说明如何处理输出,因为这超出了本问题的范围,但如果您不需要传递,请考虑写入 CSV 文件,甚至直接写入 Excel 文件出于某种原因将 XML 转移到另一个程序。有一些 Python 包可以处理写入 CSV 和 Excel 文件。

例如,无需创建中间格式,然后在将其导入 Excel 后进行操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    相关资源
    最近更新 更多