【问题标题】:ElementTree parse xml file - problem with parsingElementTree 解析 xml 文件 - 解析问题
【发布时间】:2023-03-25 08:54:01
【问题描述】:

我在解析 xml 文件中的数据时遇到问题。我正在使用 xml.etree.ElementTree 从文件中提取数据,然后将它们保存到 .csv 中。我在服务器上安装了所有必需的模块。 我知道有带有 BeutifulSoup 的 bs4 模块,但我想知道是否可以使用 ElementTree 解析此数据/xml 文件。抱歉,如果答案很简单或很明显,但我仍然是一个初学者,遇到这个问题,我无法以找到答案的方式命名问题。

在运行下面编写的 python 脚本时,我没有错误也没有结果。我真的不知道我应该改变什么。我找不到解决方案。我尝试使用不同的 child.tag 或属性,但没有结果。

我有问题的 xml 文件。:

<?xml version="1.0" encoding="utf-8"?>
<offer file_format="IOF" version="2.6" extensions="yes" xmlns="http://www.iai-shop.com/developers/iof.phtml">
    <product id="9" vat="23.0" code_on_card="BHA">
      <producer id="1308137276" name="BEAL"/>
      ...
      <price gross="175" net="142.28"/>
      <sizes>
        <size code_producer="3700288265272" code="9-uniw" weight="0">
          <stock id="0" quantity="-1"/>
          <stock id="1" quantity="4"/>
        </size>
      </sizes>
    </product>
    <product>
              ...
    </product>
              ...

以及我尝试使用的脚本(此处提取 code_on_card、price net、数量)。

(我知道有两个孩子:库存和数量,我完全可以接受第二个覆盖第一个)

import requests
import os,sys
import csv
import xml.etree.ElementTree as ET

reload(sys)
sys.setdefaultencoding('utf-8')

xml_path = '/file.xml'

xml = ET.parse(xml_path)

with open('/home/file.csv', 'wb') as f:
    c = csv.writer(f, delimiter=';')
    for product in xml.iter('product'):
    product_id = product.attrib["code_on_card"]
        for child in product:
            if child.tag == 'price':
                if child.attrib["net"] != None:
                    hurt_net = child.attrib["net"]
        for size in product.iter('size'):
            for stock in size.iter('stock'):
                if 'quantity' in stock.attrib.keys():
                    quantity = stock.attrib["quantity"]

        line = product_id, hurt_net, quantity
        c.writerow(line)

在我看来建立在类似方案上的文件工作得很好(offer -> product ->child/attrib ),比如这个:

<?xml version="1.0" encoding="UTF-8"?>
<offer file_format="IOF" version="2.5">
    <product id="2">
        <price gross="0.00" net="0.00" vat="23.0"/>
        <srp gross="0.00" net="0" vat="23.0"/>
        <sizes>
            <size id="0"  code="2-0"  weight="0" >
            </size>
        </sizes>
    </product>
        ...
    </product>
        ...

编辑: 结果应该是 .csv 文件,其中包含 code_on_card、价格净额、数量的多行(每个用于 xml 文件中的每个产品)。它应该看起来像:

BC097B.50GD.O;70.81;37
BC097B.50.A;76.75;24
BC086C.50.B;76.75;29
BGRT.L;3;96.75;28
....

EDIT2 代码原样,在 drec4s answear 之后:

import requests
import os,sys
import csv
import xml.etree.cElementTree as ET

reload(sys)
sys.setdefaultencoding('utf-8')

xml_path = '/home/platne/serwer16373/dane/z_hurtowni/pobrane/beal2.xml'

root = ET.parse(xml_path)

ns = {'offer': 'http://www.iai-shop.com/developers/iof.phtml'}

products = root.getchildren()

with open('/home/platne/serwer16373/dane/z_hurtowni/stany_magazynowe/karol/bealKa.csv', 'wb') as f:
    c = csv.writer(f, delimiter=';')
    hurtownia = 'beal'
    for product in root.iter('product'):
        qtt = [1]
        code = product.get('code_on_card')
        hurt_net = product.find('price').get('net')
        for stock in product.find('sizes').find('size').getchildren():
            qtt.append(stock.get('quantity'))
        quantity = max(qtt)


        line = 'beal-'+str(code), hurt_net, quantity
        c.writerow(line)

不知怎的 AttributeError:“ElementTree”对象没有属性“getchildren” 我有Ele

【问题讨论】:

  • 这是因为默认命名空间(see here 关于如何使用命名空间解析 XML)。如果您添加一个输出应该是什么样子的示例,也会很有帮助。
  • 另一件有用的事情是可以按原样运行的代码(请参阅stackoverflow.com/help/mcve)。
  • 默认命名空间 - 我想就是这样 - 需要时间来适应它。

标签: python parsing elementtree


【解决方案1】:

这就是我如何去解析一个带有命名空间的xml 文件。根据official documentation,最简单的方法是定义一个dictionary 指定命名空间。

from xml.etree import cElementTree as ET

root = ET.fromstring("""
<offer file_format="IOF" version="2.6" extensions="yes" xmlns="http://www.iai-shop.com/developers/iof.phtml">
    <product id="9" vat="23.0" code_on_card="BHA">
      <producer id="1308137276" name="BEAL"/>
      <price gross="175" net="142.28"/>
      <sizes>
        <size code_producer="3700288265272" code="9-uniw" weight="0">
          <stock id="0" quantity="-1"/>
          <stock id="1" quantity="4"/>
        </size>
      </sizes>
    </product>
</offer>
""")

ns = {'offer': 'http://www.iai-shop.com/developers/iof.phtml'}

products = root.getchildren()

for p in products:
    qtt = [] #to store all stock quantities
    product_id = p.get('code_on_card')
    hurt_net = p.find('offer:price', ns).get('net')
    for stock in p.find('offer:sizes', ns).find('offer:size', ns).getchildren():
        qtt.append(int(stock.get('quantity')))

    quantity = max(qtt) #or sum

line = (product_id, hurt_net, quantity)
print(line)

输出:

('BHA', '142.28', 4)

另外,我不明白您需要提取的库存数量是多少,因为您只获得了最后一个 children(stock) 值(将 sum 函数更改为 max 或任何您需要的)。

【讨论】:

  • 我认为这是答案,但我似乎无法解决。不知何故,我得到了 AttributeError: 'ElementTree' object has no attribute 'getchildren'
猜你喜欢
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2019-03-23
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 2018-01-28
相关资源
最近更新 更多