Синтаксический анализ XML: Python ElementTree, поиск элементов и его родительских элементов без других элементов в том же родительском элементе. - PullRequest
0 голосов
/ 02 октября 2019

Я использую библиотеку ElementTree в python для анализа XML-файла, который имеет следующую структуру. Я пытаюсь получить строку XML, соответствующую объекту с id = 192 со всеми его родителями (папками), но без других объектов

   <catalog>
        <folder name="entities">
            <entity id="102">

            </entity>
            <folder name="newEntities">
                <entity id="192">

                </entity>

                <entity id="2982">

                </entity>
            </folder>
        </folder>
    </catalog>

Требуемый результат должен быть

    <catalog>
        <folder name="entities">
            <folder name="newEntities">
                <entity id="192">

                </entity>
            </folder>
        </folder>
    </catalog>

при условии1-я строка XML хранится в переменной с именем xml_string

tree = ET.fromstring(xmlstring)
id = 192
required_element = tree.find(".//entity[@id='" + id + "']")

. Получает элемент xml для требуемой сущности, но не для родительских папок, какое-нибудь быстрое решение проблемы для этого?

1 Ответ

2 голосов
/ 03 октября 2019

Задача здесь состоит в том, чтобы обойти тот факт, что у ET нет родительской информации. Решение состоит в том, чтобы использовать parent_map

import copy
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom

xml = '''<catalog>
        <folder name="entities">
            <entity id="102">

            </entity>
            <folder name="newEntities">
                <entity id="192">

                </entity>

                <entity id="2982">

                </entity>
            </folder>
        </folder>
    </catalog>'''


def prettify(elem):
    """Return a pretty-printed XML string for the Element.
    """
    rough_string = ET.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")

root = ET.fromstring(xml)
parent_map = {c: p for p in root.iter() for c in p}
_id = 192
required_element = root.find(".//entity[@id='" + str(_id) + "']")
_path = [copy.deepcopy(required_element)]
while True:
    parent = parent_map.get(required_element)
    if parent:
        _path.append(copy.deepcopy(parent))
        required_element = parent
    else:
        break
idx = len(_path) - 1
while idx >= 1:
    _path[idx].clear()
    _path[idx].append(_path[idx-1])
    idx -= 1

print(prettify(_path[-1]))

output

<?xml version="1.0" ?>
<catalog>
    <folder>
        <folder>
            <entity id="192">

                </entity>



        </folder>
    </folder>
</catalog>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...