私のXMLファイルは次のようになります。
<?xml version="1.0"?>
<ItemSearchResponse xmlns="http://webservices.Amazon.com/AWSECommerceService/2008-08-19">
<Items>
<Item>
<ItemAttributes>
<ListPrice>
<Amount>2260</Amount>
</ListPrice>
</ItemAttributes>
<Offers>
<Offer>
<OfferListing>
<Price>
<Amount>1853</Amount>
</Price>
</OfferListing>
</Offer>
</Offers>
</Item>
</Items>
</ItemSearchResponse>
ListPriceを抽出するだけです。
これは私が使用しているコードです:
>> from elementtree import ElementTree as ET
>> fp = open("output.xml","r")
>> element = ET.parse(fp).getroot()
>> e = element.findall('ItemSearchResponse/Items/Item/ItemAttributes/ListPrice/Amount')
>> for i in e:
>> print i.text
>>
>> e
>>
まったく出力しません。私も試しました
>> e = element.findall('Items/Item/ItemAttributes/ListPrice/Amount')
変わりはない。
私は何を間違えていますか?
あなたが持っている2つの問題があります。
1)element
には、ドキュメント全体を再帰的にではなく、ルート要素のみが含まれます。 ElementTreeではなくElementタイプです。
2)名前空間をXMLに保持する場合、検索文字列は名前空間を使用する必要があります。
問題#1:を修正するには
変更する必要があります:
element = ET.parse(fp).getroot()
に:
element = ET.parse(fp)
問題#2を修正するには:
次のように、XMLドキュメントからxmlnsを削除できます。
<?xml version="1.0"?>
<ItemSearchResponse>
<Items>
<Item>
<ItemAttributes>
<ListPrice>
<Amount>2260</Amount>
</ListPrice>
</ItemAttributes>
<Offers>
<Offer>
<OfferListing>
<Price>
<Amount>1853</Amount>
</Price>
</OfferListing>
</Offer>
</Offers>
</Item>
</Items>
</ItemSearchResponse>
このドキュメントでは、次の検索文字列を使用できます。
e = element.findall('Items/Item/ItemAttributes/ListPrice/Amount')
完全なコード:
from elementtree import ElementTree as ET
fp = open("output.xml","r")
element = ET.parse(fp)
e = element.findall('Items/Item/ItemAttributes/ListPrice/Amount')
for i in e:
print i.text
問題#2の代替修正:
それ以外の場合は、各要素のsrearch文字列内にxmlnsを指定する必要があります。
完全なコード:
from elementtree import ElementTree as ET
fp = open("output.xml","r")
element = ET.parse(fp)
namespace = "{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}"
e = element.findall('{0}Items/{0}Item/{0}ItemAttributes/{0}ListPrice/{0}Amount'.format(namespace))
for i in e:
print i.text
両方印刷:
2260
from xml.etree import ElementTree as ET
tree = ET.parse("output.xml")
namespace = tree.getroot().tag[1:].split("}")[0]
amount = tree.find(".//{%s}Amount" % namespace).text
また、 lxml の使用を検討してください。ずっと速いです。
from lxml import ElementTree as ET
私はそのような未加工のxmlからxmlnsを取り除くことになりました:
def strip_ns(xml_string):
return re.sub('xmlns="[^"]+"', '', xml_string)
明らかにこれには非常に注意しますが、私にとってはうまくいきました。
要素ツリーは名前空間を使用するため、xmlのすべての要素は{ http://webservices.Amazon.com/AWSECommerceService/2008-08-19 } Itemsのような名前を持ちます。
そのため、検索に名前空間を含めるようにします。
search = '{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}Items/{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}Item/{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}ItemAttributes/{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}ListPrice/{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}Amount'
element.findall( search )
2260に対応する要素を与える
最も単純なアプローチの1つであり、python 3.0および他のバージョンでも以下のように動作します。
ルートを取得し、指定された「Amount」タグを取得するまで取得を開始します
from xml.etree import ElementTree as ET
tree = ET.parse('output.xml')
root = tree.getroot()
#print(root)
e = root.find(".//{http://webservices.Amazon.com/AWSECommerceService/2008-08-19}Amount")
print(e.text)