我在 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/