【问题标题】:add integers in nested XML child elements using python使用python在嵌套的XML子元素中添加整数
【发布时间】:2018-05-15 20:19:08
【问题描述】:

我收到一个包含许多子元素的 XML 文档,我需要提取信息然后导出到 CSV 或文本文档,以便导入到 Quickbooks。 XML 树如下所示:

<MODocuments>
  <MODocument>
    <Document>TX1126348</Document>
    <DocStatus>P</DocStatus>
    <DateIssued>20180510</DateIssued>
    <ApplicantName>COMPANY FRUIT &amp; VEGETABLE</ApplicantName>
    <MOLots>
      <MOLot>
        <LotID>A</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>15500</TotalPounds>
      </MOLot>
      <MOLot>
        <LotID>B</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>175</TotalPounds>
      </MOLot>
      <MOLot>
        <LotID>C</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>7500</TotalPounds>
      </MOLot>
      <MOLot>
        <LotID>D</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>300</TotalPounds>
      </MOLot>
    </MOLots>
  </MODocument>
  <MODocument>
    <Document>TX1126349</Document>
    <DocStatus>P</DocStatus>
    <DateIssued>20180511</DateIssued>
    <ApplicantName>COMPANY FRUIT &amp; VEGETABLE</ApplicantName>
    <MOLots>
      <MOLot>
        <LotID>A</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>25200</TotalPounds>
      </MOLot>
      <MOLot>
        <LotID>B</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>16800</TotalPounds>
      </MOLot>
    </MOLots>
  </MODocument>
  <MODocument>
    <Document>TX1126350</Document>
    <DateIssued>20180511</DateIssued>
    <ApplicantName>COMPANY FRUIT &amp; VEGETABLE</ApplicantName>
    <MOLots>
      <MOLot>
        <LotID>A</LotID>
        <ProductVariety>Yellow</ProductVariety>
        <TotalPounds>14100</TotalPounds>
      </MOLot>
    </MOLots>
  </MODocument>
</MODocuments>

我需要从每个 MODocument 父级中提取 TotalPounds,以便输出如下所示: 文件编号、申请人姓名和总磅数为该文件中的所有 MOLots 相加。

TX1126348   COMPANY FRUIT & VEGETABLE 23475
TX1126349   COMPANY FRUIT & VEGETABLE 42000
TX1126350   COMPANY FRUIT & VEGETABLE 14100

这是我正在使用的代码:

import xml.etree.ElementTree as ET
tree = ET.parse('TX_959_20180514131311.xml')
root = tree.getroot()

docCert = []
docComp = []
totalPounds=[]

for MODocuments in root:
    for MODocument in MODocuments:
        docCert.append(MODocument.find('Document').text)
        docComp.append(MODocument.find('ApplicantName').text)
        for MOLots in MODocument:
            for MOLot in MOLots:
                totalPounds.append(int(MOLot.find('TotalPounds').text))

for i in range(len(docCert)):
    print(i, docCert[i],' ', docComp[i], totalPounds[i])

这是我的输出,我不知道如何将每个文档的总数相加。请帮忙。

0 TX1126348   COMPANY FRUIT & VEGETABLE 15500
1 TX1126349   COMPANY FRUIT & VEGETABLE 175
2 TX1126350   COMPANY FRUIT & VEGETABLE 7500

【问题讨论】:

    标签: python xml xml-parsing quickbooks iif


    【解决方案1】:

    如果你可以使用 lxml,你可以让 XPath sum() 函数为你计算所有的 TotalPounds。

    示例...

    from lxml import etree
    import csv
    
    tree = etree.parse("TX_959_20180514131311.xml")
    
    with open("output.csv", "w", newline="") as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=",", quoting=csv.QUOTE_MINIMAL)
        for mo_doc in tree.xpath("/MODocuments/MODocument"):
            csvwriter.writerow([mo_doc.xpath("Document")[0].text,
                                mo_doc.xpath("ApplicantName")[0].text,
                                int(mo_doc.xpath("sum(MOLots/MOLot/TotalPounds)"))])
    

    “output.csv”的内容...

    TX1126348,COMPANY FRUIT & VEGETABLE,23475
    TX1126349,COMPANY FRUIT & VEGETABLE,42000
    TX1126350,COMPANY FRUIT & VEGETABLE,14100
    

    此外,您可以通过使用csv 编写输出来对引用、分隔符等进行大量控制。

    【讨论】:

    • 看来我需要安装lxml。我有一台 Windows 机器,所以让我做一些研究并尝试这个解决方案。非常感谢!
    • @Simon - 我也有一台 Windows 机器,lxml 没有任何问题。我使用 pip 安装。 lxml.de/installation.html
    • 我安装了 lxml 并运行,创建了 output.csv,但它完全是空白的。有什么想法吗?
    • @Simon - 对不起。我最初使用 python 2.7 进行了测试。当我使用 python 3.6 运行它时,我能够重现该错误。该错误是由我将 csv 作为二进制文件打开引起的。我在我的代码中更新了open() 并使用 python 3.6 进行了测试,它现在对我有用。 (不要忘记更新 xpath 以考虑您的额外父级别。)
    • @Simon - 不客气。他们的网站 (lxml.de) 有很多很好的信息。任何我在那里找不到的东西,我都可以在 stackoverflow 上找到 :-)
    【解决方案2】:

    看起来totalPounds 中的项目将多于docCertdocComp 中的项目。我认为你需要做这样的事情:

    for MODocuments in root:
        for MODocument in MODocuments:
            docCert.append(MODocument.find('Document').text)
            docComp.append(MODocument.find('ApplicantName').text)
            sub_total = 0
            for MOLots in MODocument:
                for MOLot in MOLots:
                    sub_total += int(MOLot.find('TotalPounds').text)
            totalPounds.append(sub_total)
    

    【讨论】:

    • 这完全适用于添加 sub_total!非常感谢你!我喜欢 Daniel Haley 的另一个答案,因为它将它吐出到 CSV,但我需要先对其进行测试。
    猜你喜欢
    • 2019-11-28
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多