如何将XML数据解析为python中的列表

问题描述 投票:1回答:1

我正在尝试获取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
python python-3.x xml-parsing elementtree
1个回答
0
投票

调试是您的朋友...

我在多重儿童/父母关系中挣扎。

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

enter image description here

[有多种方法可以在命令行上执行,也可以使用像iPython这样的REPL等,但是我发现在像[[VS Code或PyCharm要走的路。他们的调试器无需在任何地方添加print语句来测试代码,重写代码以暴露更多必须打印到控制台的变量,等等。

调试器使您可以在代码执行中的任何时候,将所有变量视为快照,完全像Python解释器看到它们一样。您可以:

    逐行浏览代码,并在窗口中实时查看变量的变化
  • 使用您关心的变量设置一个单独的监视窗口
  • 和仅在将变量设置为特定值等情况下才会发生的设置断点。>
  • 具有XML find方法的子层次结构

在我遍历代码时检查变量,似乎find()方法正在各个级别(而不只是在顶层)上遍历Element中的子级。当您使用x.find('tracking')时,它将直接找到mailPiece节点。如果打印tag属性而不是text属性,您会看到它是'mailPiece'(请参见上面的调试窗口)。

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

这里有一些代码将所有这些都拉入列表和字典的组合层次结构中,然后可以用来构建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后就需要进行操作。

© www.soinside.com 2019 - 2024. All rights reserved.