python - 使用 lxml 将一个 xml 复制到 python 中的另一个

标签 python xml loops lxml

我在 python 中有以下代码

from lxml import etree

offers = etree.parse(r'prices.xml')

print("offers\n")

target = offers.xpath('//offer[./vendor/text()="Qtap"]')
length = len(target)
for i in  range(length):
    print(target[i])
    etree.ElementTree(target[i]).write('output.xml', encoding='utf-8', xml_declaration=True)

我只是读取了 xml 文件。使用 xpath 从中读取数据并希望将其全部写入另一个文件中。大约有 2000 个元素显示为长度,但脚本只写最后一个。抱歉,我知道我的问题相当愚蠢,但这是我在 Python 上的第一个程序。

尽管已接受的答案实际上有效。我将给出 xml 文件的简单示例。 作为输入,我得到类似的东西:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<yml_catalog date="2022-02-16 18:16">
    <shop>
        <purchase_currencies>
            <currency id="USD" rate="28.3"/>
            <currency id="EUR" rate="32.18"/>
            <currency id="UAH" rate="1"/>
        </purchase_currencies>
        <categories></categories>
        <offers>
            <offer id="SD00025386">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/9/19289.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/9/19289/19289_1.jpg</picture>
                <name>Трап ANI Plast TA1612 горизонтальний з нержавіючою решіткою 150x150</name>
                <available>true</available>
                <oldCode>19289</oldCode>
                <model>TA1612</model>
                <purchase_price>405.158</purchase_price>
                <currency>UAH</currency>
                <retail_price>691</retail_price>
                <retail_oldprice></retail_oldprice>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="1"></outlet>
                    <outlet id="86" name="Київ" instock="3"></outlet>
                    <outlet id="87" name="Україна" instock="16"></outlet>
                </outlets>
                <vendor>Ани Пласт</vendor>
                <vendorCode>SD00025386</vendorCode>
            </offer>
            <offer id="SD00025387">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/9/19290.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/9/19290/19290_1.jpg</picture>
                <name>Трап ANI Plast TA1712 вертикальний з нержавіючою решіткою 150х150</name>
                <available>true</available>
                <oldCode>19290</oldCode>
                <model>TA1712</model>
                <purchase_price>354.843</purchase_price>
                <currency>UAH</currency>
                <retail_price>605</retail_price>
                <retail_oldprice></retail_oldprice>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="20"></outlet>
                    <outlet id="86" name="Київ" instock="3"></outlet>
                    <outlet id="87" name="Україна" instock="20"></outlet>
                </outlets>
                <vendor>Ани Пласт</vendor>
                <vendorCode>SD00025387</vendorCode>
            </offer>
<offer id="SD00022605">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_1.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_2.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_3.jpg</picture>
                <name>Донний клапан для раковини Qtap L02 з переливом</name>
                <available>true</available>
                <oldCode>16508</oldCode>
                <model>QTL02</model>
                <purchase_price>4.635</purchase_price>
                <currency>EUR</currency>
                <retail_price>261</retail_price>
                <retail_oldprice/>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="0"/>
                    <outlet id="86" name="Київ" instock="0"/>
                    <outlet id="87" name="Україна" instock="3"/>
                </outlets>
                <vendor>Qtap</vendor>
                <vendorCode>SD00022605</vendorCode>
            </offer>
            <offer id="SD00022606">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16509.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16509/16509_1.jpg</picture>
                <name>Донний клапан для раковини Qtap L01 з переливом</name>
                <available>true</available>
                <oldCode>16509</oldCode>
                <model>QTL01</model>
                <purchase_price>1.236</purchase_price>
                <currency>EUR</currency>
                <retail_price>70</retail_price>
                <retail_oldprice/>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="0"/>
                    <outlet id="86" name="Київ" instock="0"/>
                    <outlet id="87" name="Україна" instock="1"/>
                </outlets>
                <vendor>Qtap</vendor>
                <vendorCode>SD00022606</vendorCode>
            </offer>

我的任务是获得供应商 QTAP 的所有报价。所以输出将是:

<offer id="SD00022605">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_1.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_2.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16508/16508_3.jpg</picture>
                <name>Донний клапан для раковини Qtap L02 з переливом</name>
                <available>true</available>
                <oldCode>16508</oldCode>
                <model>QTL02</model>
                <purchase_price>4.635</purchase_price>
                <currency>EUR</currency>
                <retail_price>261</retail_price>
                <retail_oldprice/>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="0"/>
                    <outlet id="86" name="Київ" instock="0"/>
                    <outlet id="87" name="Україна" instock="3"/>
                </outlets>
                <vendor>Qtap</vendor>
                <vendorCode>SD00022605</vendorCode>
            </offer>
            <offer id="SD00022606">
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16509.jpg</picture>
                <picture>https://isw.b2b-sandi.com.ua/imagecache/full/1/6/16509/16509_1.jpg</picture>
                <name>Донний клапан для раковини Qtap L01 з переливом</name>
                <available>true</available>
                <oldCode>16509</oldCode>
                <model>QTL01</model>
                <purchase_price>1.236</purchase_price>
                <currency>EUR</currency>
                <retail_price>70</retail_price>
                <retail_oldprice/>
                <retail_currency>UAH</retail_currency>
                <outlets>
                    <outlet id="85" name="Харків" instock="0"/>
                    <outlet id="86" name="Київ" instock="0"/>
                    <outlet id="87" name="Україна" instock="1"/>
                </outlets>
                <vendor>Qtap</vendor>
                <vendorCode>SD00022606</vendorCode>
            </offer> 

是的,问题是每次迭代时都会覆盖文件的循环

最佳答案

这是因为循环中的 write() 方法每次运行时都会覆盖前一个元素。试试这个方法:

qtaps = etree.XML("""<offers/>""".encode())
targets = offers.xpath('//offer[./vendor/text()="Qtap"]')
for target in targets:
    qtaps.insert(-1,target)
with open('output.xml', 'wb') as doc:
    doc.write(etree.tostring(qtaps, pretty_print = True, encoding='utf-8', xml_declaration=True))

看看它是否有效。

关于python - 使用 lxml 将一个 xml 复制到 python 中的另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71196127/

相关文章:

php - Mysql从XML插入字段名称为 "hyphen"

python - 使用 Python Loop 从 Excel 文件创建多个 .txt 文件

javascript - 解析 Google Stock XML

python - Wtforms 表单,用于访问嵌入式表单字段的语法

python - 如何从类中获取对象名称?

python - 小牛升级后 virtualenvwrapper 的终端问题

c++ - GDBus 自省(introspection) xml 中的多个完整类型

java - 根据内存和 GC 在循环内部或外部声明对象

c++ - 在提示再次运行程序时尝试进行错误纠正

python - 如何使用一张图表上显示的两个字典中的值来注释 pandas 条形图?