Python minidom: как получить доступ к элементу

Я работаю над разбором XML-листа в Python. XML имеет такую ​​структуру:

<layer1>
    <layer2>
        <element>
            <info1></info1>
        </element>
        <element>
            <info1></info1>
        </element>
        <element>
            <info1></info1>
        </element>
    </layer2>
</layer1>

Без layer2 у меня нет проблем с доступом к данным в info1. Но со слоем 2 у меня действительно проблемы. Их я могу адресовать info1 с: root.firstChild.childNodes[0].childNodes[0].data

Итак, я подумал, что я могу сделать это примерно так: root.firstChild.firstChild.childNodes[0].childNodes[0].data

########## Solution

Вот как я решил свою проблему: из xml.etree импортировать cElementTree как ET

из xml.etree импортировать cElementTree как ET

tree = ET.parse("test.xml")
root = tree.getroot()

for elem in root.findall('./layer2/'):
    for node in elem.findall('element/'):
        x = node.find('info1').text
        if x != "abc":
            elem.remove(node)

person Leagis    schedule 24.04.2013    source источник
comment
Есть ли у вас должна причина использовать minidom вместо ElementTree API?   -  person Martijn Pieters    schedule 24.04.2013


Ответы (2)


Не используйте minidom API, если можете. Вместо этого используйте ElementTree API; в xml.dom.minidom документации прямо указано, что:

Пользователям, которые еще не знакомы с DOM, следует вместо этого рассмотреть возможность использования модуля xml.etree.ElementTree для обработки XML.

Вот небольшой пример, который использует ElementTree API для доступа к вашим элементам:

from xml.etree import ElementTree as ET

tree = ET.parse('inputfile.xml')

for info in tree.findall('.//element/info1'):
    print info.text

При этом используется выражение XPath для перечисления всех элементов info1, содержащихся внутри элемента element, независимо от их положения в общем XML-документе.

Если вам нужен только первый элемент info1, используйте .find():

print tree.find('.//info1').text

С DOM API .firstChild может легко быть узлом Text вместо узла Element; вам всегда нужно перебирать последовательность .childNotes, чтобы найти первое совпадение Element:

def findFirstElement(node):
    for child in node.childNodes:
        if child.nodeType == node.ELEMENT_NODE:
            return child

но в вашем случае, возможно, используйте .getElementsByTagName() достаточно:

root.getElementsByTagName('info1').data
person Martijn Pieters    schedule 24.04.2013
comment
Спасибо, это мне помогает :) Быстрый вопрос: for context in root.findall('.//element/'):info = context.find('info1').text if info != a: root.remove(context) Не работает. Пишет, что его нет в списке? - person Leagis; 29.04.2013
comment
Хорошо, я нашел решение сам :) Спасибо за вашу поддержку, ребята! Я отредактирую вопрос, чтобы показать мой результат - person Leagis; 29.04.2013
comment
@FlorianKanus: Нет, не редактируйте свой вопрос (потому что это ваш вопрос!) Вместо этого просто примите лучший ответ (как вы это сделали) или напишите свой собственный. - person Juuso Ohtonen; 17.06.2013

Это работает? (я не в восторге от python, просто быстро подумал)

name[0].firstChild.nodeValue
person Tyler    schedule 24.04.2013