Поиск по шаблону на любой вложенной глубине с использованием xml.etree.ElementTree
У меня есть группа файлов XML, которые содержат записи, такие как
<group name="XXX common string">
<value val="12" description="a dozen">
<text>one less than a baker's dozen</text>
</value>
<value val="13" description="a baker's dozen">
<text>One more than a dozen</text>
</value>
</group>
<group name="YYY common string">
<value val="42" description="the answer">
<text>What do you get if you multiple 6 by 9?</text>
</value>
</group>
Есть ли простой способ, используя import xml.etree.ElementTree as ET
а также
parser = ET.XMLParser()
parser.parser.UseForeignDTD(True)
if (args.info) or (args.diagnostics):
print('Parsing input file : ' + inputFileName)
tree = ET.parse(inputFileName, parser=parser)
root = tree.getroot()
искать только <group>
элементы, имя которых содержит "общую строку" для определенного value val
?
Важно: эти группы расположены на разных глубинах в разных файлах.
2 ответа
Это было немного сложно, потому что ваш собственный код не будет работать с примерами данных, которые вы разместили в своем вопросе (например, ничего там не содержит строку error
и нет id
атрибуты, и ваш код не для поиска "конкретного value
val
что казалось одним из твоих требований). Но вот несколько идей...
Для нахождения всех group
элементы, которые содержат common string
в name
атрибут, вы можете сделать что-то вроде этого:
>>> matching_groups = []
>>> for group in tree.xpath('//group[contains(@name, "common string")]'):
... matching_groups.append[group]
...
Что с учетом ваших данных образца приведет к:
>>> print '\n'.join([etree.tostring(x) for x in matching_groups])
<group name="XXX common string">
<value val="12" description="a dozen">
<text>one less than a baker's dozen</text>
</value>
<value val="13" description="a baker's dozen">
<text>One more than a dozen</text>
</value>
</group>
<group name="YYY common string">
<value val="42" description="the answer">
<text>What do you get if you multiple 6 by 9?</text>
</value>
</group>
Если вы хотите ограничить результаты только group
элементы, которые содержат value
элемент с атрибутом val
== 42
Вы можете попробовать:
>>> matching_groups = []
>>> for group in tree.xpath('//group[contains(@name, "common string")][value/@val = "42"]'):
... matching_groups.append(group)
...
Что даст:
>>> print '\n'.join([etree.tostring(x) for x in matching_groups])
<group name="YYY common string">
<value val="42" description="the answer">
<text>What do you get if you multiple 6 by 9?</text>
</value>
</group>
Проблемы заключались в 1) поиске по групповому имени группы и 2) том факте, что группы были размещены на разных уровнях в разных файлах.
Я реализовал этот метод грубой силы, чтобы создать словарь всех таких записей об ошибках в группе с именем ошибки в любом месте файла.
Я оставляю это здесь для потомков и приглашаю больше решений для слонов.
import xml.etree.ElementTree as ET
parser = ET.XMLParser()
parser.parser.UseForeignDTD(True)
tree = ET.parse(inputFileName, parser=parser)
root = tree.getroot()
args.errorDefinitions = {}
for element in tree.iter():
if element.tag == 'group':
if 'error' in element.get('name').lower():
if element._children:
for errorMessage in element._children[0]._children:
args.errorDefinitions[errorMessage.get('name')] = \
{'id': errorMessage.get('id'), \
'description': element._children[0].text}