python #xml #list #python-xmlschema
#python #xml #Список #python-xmlschema
Вопрос:
У меня есть XML-файл со следующим форматом:
<batch>
<type1 type="application/pdf" file="1234.pdf">
<...></...>
<...></...>
<description>Description 1</description>
<...></...>
<...></...>
</type1>
<type2 type="application/pdf" file="23456.pdf">
<...></...>
<...></...>
<description>Description 1</description>
<...></...>
<...></...>
</type2>
<type1 type="application/pdf" file="1235.pdf">
<...></...>
<...></...>
<description>Description 2</description>
<...></...>
<...></...>
</type1>
</batch>
Я хочу получить список type1, type2 в списке описаний для этого типа в xml. Результатом списка является [‘{blabla.com }тип1’, ‘{blabla.com/2 }тип2’, ‘{blabla.com/3 }тип3’, ‘{blabla.com }тип4’ и т.д. ]
Я попытался:
test = ET.parse("...\index.xml")
type_list = []
for type in test.iter():
type_list.append(type.tag)
type_list = list(set(type_list))
чтобы получить все типы в xml. Но тогда как я могу получить все описания для каждого типа?
Результат, который я хочу иметь:
type1: Description 1, Description 2
type2: Description 1, ...
Комментарии:
1.
type.findall('description')
чтобы получить теги описания внутриtype
узла2. Результатом type_list является [‘{ blabla.com }тип1′, ‘{ blabla.com }тип2′, ‘{ blabla.com }тип3′, ‘{ blabla.com }type4′ и т.д. ] Итак, я пробовал это раньше, но это не сработало
Ответ №1:
некрасивая обработка пространства имен, но должна работать
import xml.etree.ElementTree as ET
from collections import defaultdict
test = ET.parse("test.xml")
type_list = defaultdict(set)
ns="{blabla.com}"
for type_ in test.iter():
if type_.tag.startswith(ns 'type'):
ttag=type_.tag.split(ns)[1]
descrs = type_.findall(ns 'description')
for descr in descrs:
type_list[ttag].add(descr.text)
print(type_list)
Комментарии:
1. Зачем нужен трюк с пространством имен? Почему бы просто не
list(root)
перебрать типы?2. @balderman op не обновил свой пост, но в комментариях он сказал, что существует пространство имен
Ответ №2:
смотрите ниже
import xml.etree.ElementTree as ET
from collections import defaultdict
data = defaultdict(list)
xml = '''<batch>
<type1 type="application/pdf" file="1234.pdf">
<description>Description 1</description>
</type1>
<type2 type="application/pdf" file="23456.pdf">
<description>Description 1</description>
</type2>
<type1 type="application/pdf" file="1235.pdf">
<description>Description 2</description>
</type1>
</batch>'''
root = ET.fromstring(xml)
for _type in list(root):
data[_type.tag].append(_type.find('description').text)
print(data)
вывод
defaultdict(<class 'list'>, {'type1': ['Description 1', 'Description 2'], 'type2': ['Description 1']})