亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python 高效地從 XML 中提取嵌套元素

Python 高效地從 XML 中提取嵌套元素

慕斯709654 2024-01-16 10:46:32
我正在嘗試解析大量包含大量嵌套元素的 XML 文件,以收集稍后使用的特定信息。由于文件數量巨大,我試圖盡可能高效地完成此操作,以減少處理時間。我可以使用 xpath 提取所需的信息,如下所示,但似乎效率很低。特別是必須運行第二個 for 循環來使用另一個 xpath 搜索提取結果值。我可以使用更有效的方法來獲得下面所需的輸出嗎?我可以通過單個 xpath 查詢收集所需的信息嗎?所需的解析格式:Id? ? ? ? ? ? ?Object? ? Type? ? ? ? ? ? ?ResultPackages? ? ? ?total? ? ?totalPackages? ? 1200DeliveryMethod priority? packagesSent? ? ?100DeliveryMethod express? ?packagesSent? ? ?200DeliveryMethod ground? ? packagesSent? ? ?300DeliveryMethod priority? packagesReceived 100DeliveryMethod express? ?packagesReceived 200DeliveryMethod ground? ? packagesReceived 300XML 示例:<?xml version="1.0" encoding="utf-8"?>? ? <Data>? ? ? ? <Location localDn="Chicago"/>? ? ? ? <Info Id="Packages">? ? ? ? ? ? <job jobId="1"/>? ? ? ? ? ? <Type pos="1">totalPackages</Type>? ? ? ? ? ? <Value Object="total">? ? ? ? ? ? ? ? <result pos="1">1200</result>? ? ? ? ? ? </Value>? ? ? ? </Info>? ? ? ? <Info Id="DeliveryMethod">? ? ? ? ? ? <job jobId="1"/>? ? ? ? ? ? <Type pos="1">packagesSent</Type>? ? ? ? ? ? <Type pos="2">packagesReceived</Type>? ? ? ? ? ? <Value Object="priority">? ? ? ? ? ? ? ? <result pos="1">100</result>? ? ? ? ? ? ? ? <result pos="2">100</result>? ? ? ? ? ? </Value>? ? ? ? ? ? <Value Object="express">? ? ? ? ? ? ? ? <result pos="1">200</result>? ? ? ? ? ? ? ? <result pos="2">200</result>? ? ? ? ? ? </Value>? ? ? ? ? ? <Value Object="ground">? ? ? ? ? ? ? ? <result pos="1">300</result>? ? ? ? ? ? ? ? <result pos="2">300</result>? ? ? ? ? ? </Value>? ? ? ? </Info>? </Data>是否可以通過迭代來獲取所有信息tree.xpath('//*')?
查看完整描述

2 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

其中一項優化不會像您現在使用tree.xpath('//*')if 語句那樣遍歷所有標簽并進行檢查。這可以替換為tree.xpath('//Type')


接下來需要優化的是迭代值。Value您無需一遍又一遍地迭代( tree.xpath('//Value')),您可以獲得標簽的所有同級Values標簽Typeelem.xpath('./following-sibling::Value')


from lxml import etree


xml_file = open('stack_sample.xml')

tree = etree.parse(xml_file)

root = tree.getroot()


for elem in tree.xpath('//Type'):

    _id = elem.getparent().attrib["Id"]

    _type = elem.text

    _position = elem.attrib["pos"]

    values = elem.xpath('./following-sibling::Value')

    for value in values:

        _object = value.attrib['Object']

        _result = value.xpath(f'./result[@pos={_position}]/text()')[0]

        print(_id, _type, _object, _result)

這將打印出:


Packages totalPackages total 1200

DeliveryMethod packagesSent priority 100

DeliveryMethod packagesSent express 200

DeliveryMethod packagesSent ground 300

DeliveryMethod packagesReceived priority 100

DeliveryMethod packagesReceived express 200

DeliveryMethod packagesReceived ground 300

編輯

這是針對特定情況的解決方案,其中我們確定resultinValue標簽的數量等于與其他解決方案Type是同級的標簽的數量Value,另外解決方案假設Type和result按相同pos屬性排序。


請記住,這是一種非常具體的解決方案,而不是通用的解決方案。


from lxml import etree


xml_file = open('stack_sample.xml')

tree = etree.parse(xml_file)

root = tree.getroot()


for elem in tree.xpath('//Type'):

    _id = elem.getparent().attrib["Id"]

    _type = elem.text

    _objects = elem.xpath('./following-sibling::Value/@Object')

    _results = elem.xpath('./following-sibling::Value/result/text()')

    for _object, _result in zip(_objects, _results):

            print(_id, _type, _object, _result)

輸出:


Packages totalPackages total 1200

DeliveryMethod packagesSent priority 100

DeliveryMethod packagesSent express 100

DeliveryMethod packagesSent ground 200

DeliveryMethod packagesReceived priority 100

DeliveryMethod packagesReceived express 100

DeliveryMethod packagesReceived ground 200


查看完整回答
反對 回復 2024-01-16
?
茅侃侃

TA貢獻1842條經驗 獲得超21個贊

//*如果您不迭代所有標簽( ),而只是迭代,也許性能會更高<Value>:


from lxml import etree


xml_file = open('stack_sample.xml')

tree = etree.parse(xml_file)

root = tree.getroot()


for val in tree.xpath('//Value'):

    t = {t.get('pos'): t.text for t in val.getparent().xpath('./Type')}

    for r in val.xpath('./result'):

        print(val.getparent().get('Id'), val.get('Object'), t[r.get('pos')], r.text)

印刷:


Packages total totalPackages 1200

DeliveryMethod priority packagesSent 100

DeliveryMethod priority packagesReceived 100

DeliveryMethod express packagesSent 200

DeliveryMethod express packagesReceived 200

DeliveryMethod ground packagesSent 300

DeliveryMethod ground packagesReceived 300


查看完整回答
反對 回復 2024-01-16
  • 2 回答
  • 0 關注
  • 188 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號