Допустим, у меня есть некоторые данные XML на Интернет-продукт с несколькими ценами:Разбор данных 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 в виде упрощенного Словаре, который выглядит примерно так:
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)
, но тогда, если я также хочу, чтобы эта функция преобразует значение в соответствующий тип (например: string, float или int), должен ли я иметь параметр, который задает тип, подобный 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
}
Является ли это лучший способ сделать то, что я пытаюсь сделать? Я чувствую, что создаю проблемы для себя в будущем.