46

我的 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')

没有不同。

我究竟做错了什么?

4

5 回答 5

69

你有2个问题。

1)element仅包含根元素,而不是递归地包含整个文档。它的类型是 Element 而不是 ElementTree。

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 的替代修复:

否则,您需要在搜索字符串中为每个元素指定 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

于 2009-08-23T20:02:48.690 回答
8
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
于 2009-08-23T21:11:16.837 回答
7

元素树使用命名空间,因此 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 的元素

于 2009-08-23T20:23:54.000 回答
6

我最终像这样从原始 xml 中剥离了 xmlns:

def strip_ns(xml_string):
    return re.sub('xmlns="[^"]+"', '', xml_string)

显然要非常小心,但这对我来说效果很好。

于 2012-04-27T00:24:28.833 回答
2

最直接的方法之一,甚至适用于 python 3.0 和其他版本,如下所示:

它只是获取根并开始进入它,直到我们获得指定的“数量”标签

 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)
于 2017-10-13T17:08:08.703 回答