我在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>
是的,問題是在每次迭代時覆寫檔案的回圈
uj5u.com熱心網友回復:
那是因為您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))
看看它是否有效。
uj5u.com熱心網友回復:
由于聽起來您只需要洗掉<offer>XML 中的節點,因此請考慮 XPath 的通用兄弟XSLT,這是一種用于轉換 XML 檔案的專用語言。Python 的lxml庫可以運行 XSLT 1.0 腳本。
具體來說,身份模板和空模板可以在vendor!='Qtap'沒有單個for回圈的情況下洗掉所需的節點 ()。下面將保留具有較少<offer>節點的 XML 的原始結構。
XSLT (另存為 .xsl 檔案,一種特殊的 XML 檔案)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- EMPTY TEMPLATE TO REMOVE CONTENT -->
<xsl:template match="offer[vendor!='Qtap']"/>
</xsl:stylesheet>
Python
import lxml.etree as lx
# PARSE XML AND XSLT
doc = lx.parse("input.xml")
style = lx.parse("style.xsl")
# CONFIGURE AND RUN TRANSFORMER
transformer = lx.XSLT(style)
result = transformer(doc)
# OUTPUT TO FILE
result.write_output("output.xml")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/430485.html
上一篇:將注釋檔案添加到XSD子元素
下一篇:使用awk替換xml標記值
