解析XML:PythonElementTree,查找元素及其父元素,而不在同一父元素中查找其他元素

解析XML:PythonElementTree,查找元素及其父元素,而不在同一父元素中查找其他元素,python,xml,python-2.7,Python,Xml,Python 2.7,我正在使用python的ElementTree库解析一个XML文件,该文件具有以下结构。我正在尝试获取对应于id=192的实体的xml字符串,该实体有其所有父级(文件夹),但没有其他实体 <catalog> <folder name="entities"> <entity id="102"> </entity> <folder name="newE

我正在使用python的ElementTree库解析一个XML文件,该文件具有以下结构。我正在尝试获取对应于id=192的实体的xml字符串,该实体有其所有父级(文件夹),但没有其他实体

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

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

                </entity>

                <entity id="2982">

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

这将获取所需实体的xml元素,而不是父文件夹,对此有任何快速解决方案吗?

这里的挑战是绕过ET没有父信息这一事实。解决方案是使用
parent\u 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]))
导入副本
将xml.etree.ElementTree作为ET导入
将xml.dom.minidom作为minidom导入
xml=“”
'''
def美化(要素):
“”“为元素返回打印精美的XML字符串。
"""
粗字符串=ET.tostring(元素“utf-8”)
重解析=minidom.parseString(粗字符串)
返回重新解析的.toprettyxml(indent=“\t”)
root=ET.fromstring(xml)
parent_map={c:p代表根中的p.iter()代表p}中的c
_id=192
必需的_元素=root.find(“.//实体[@id=”+str(_id)+“]”)
_path=[copy.deepcopy(必需的元素)]
尽管如此:
parent=parent\u map.get(必需的\u元素)
如果是家长:
_path.append(copy.deepcopy(父级))
必需的元素=父元素
其他:
打破
idx=len(_路径)-1
当idx>=1时:
_路径[idx]。清除()
_路径[idx]。追加(_路径[idx-1])
idx-=1
打印(美化(_路径[-1]))
输出

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

                </entity>



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

这里的挑战是绕过ET没有父信息这一事实。解决方案是使用
parent\u 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]))
导入副本
将xml.etree.ElementTree作为ET导入
将xml.dom.minidom作为minidom导入
xml=“”
'''
def美化(要素):
“”“为元素返回打印精美的XML字符串。
"""
粗字符串=ET.tostring(元素“utf-8”)
重解析=minidom.parseString(粗字符串)
返回重新解析的.toprettyxml(indent=“\t”)
root=ET.fromstring(xml)
parent_map={c:p代表根中的p.iter()代表p}中的c
_id=192
必需的_元素=root.find(“.//实体[@id=”+str(_id)+“]”)
_path=[copy.deepcopy(必需的元素)]
尽管如此:
parent=parent\u map.get(必需的\u元素)
如果是家长:
_path.append(copy.deepcopy(父级))
必需的元素=父元素
其他:
打破
idx=len(_路径)-1
当idx>=1时:
_路径[idx]。清除()
_路径[idx]。追加(_路径[idx-1])
idx-=1
打印(美化(_路径[-1]))
输出

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

                </entity>



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


@MartinHonnen很抱歉输入错误,在
find()
调用中,在xpath字符串的末尾添加
+“/…”
。@MartinHonnen很抱歉输入错误,在
find()
调用中,在xpath字符串的末尾添加
+“/…”