Получить список описаний для каждого типа в xml с помощью Python

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']})