【发布时间】:2017-02-09 01:20:40
【问题描述】:
假设我有一些关于具有多种价格的在线产品的 XML 数据:
<Response>
<TotalOffers>6</TotalOffers>
<LowPrices>
<LowPrice condition="new">
<CurrencyCode>USD</CurrencyCode>
<Amount>15.50</Amount>
</LowPrice>
<LowPrice condition="used">
<CurrencyCode>USD</CurrencyCode>
<Amount>22.86</Amount>
</LowPrice>
</LowPrices>
</Response>
我的最终目标是通过一个函数来传递它,该函数将 XML 解析为简化的 dict 形式,如下所示:
response = {
'total_offers': 6,
'low_prices': [
{'condition': "new", 'currency': "USD", 'amount': 15.50},
{'condition': "used", 'currency': "USD", 'amount': 22.86},
]
}
使用 lxml 库,这非常简单。我只需要指定 xpath 来查找每个值,然后处理缺少预期数据的异常,例如获取 TotalOffers 值 (6) 我会这样做:
# convert xml to etree object
tree_obj = etree.fromstring(xml_text)
# use xpath to find values that I want in this tree object
matched_els = tree_obj.xpath('//TotalOffers')
# xpath matches are returned as a list
# since there could be more than one match grab only the first one
first_match_el = matched_els[0]
# extract the text and print to console
print first_match_el.text
# >>> '6'
现在我的想法是我可以编写一个像get_text(tree_obj, xpath_to_value) 这样的函数,但是如果我还希望这个函数将值转换为适当的类型(例如:字符串、浮点数或整数)我应该有一个指定的参数吗?像get_text(tree_obj, xpath_to_value, type='float')这样的类型?
因为如果我这样做,我创建 dict 的下一步将是这样的:
low_prices = []
low_prices_els = tree_obj.xpath('//LowPrices')
for el in low_prices_els:
low_prices.append(
{
'condition': get_text(el, './@condition', type='str'),
'currency': get_text(el, './CurrencyCode', type='str'),
'amount': get_text(el, './Amount', type='float')
}
)
response = {
'total_offers': get_text(tree_obj, '//TotalOffers', type='int'),
'low_prices': low_prices
}
这是完成我想做的事情的最佳方式吗?我觉得我在给自己制造未来的问题。
【问题讨论】:
标签: python xml xpath xml-parsing lxml