Чтение XML с использованием Python minidom и итерация по каждому узлу

У меня есть структура XML, которая выглядит следующим образом, но в гораздо большем масштабе:

<root>
    <conference name='1'>
        <author>
            Bob
        </author>
        <author>
            Nigel
        </author>
    </conference>
    <conference name='2'>
        <author>
            Alice
        </author>
        <author>
            Mary
        </author>
    </conference>
</root>

Для этого я использовал следующий код:

dom = parse(filepath)
conference=dom.getElementsByTagName('conference')
for node in conference:
    conf_name=node.getAttribute('name')
    print conf_name
    alist=node.getElementsByTagName('author')
    for a in alist:
        authortext= a.nodeValue
        print authortext

Тем не менее, авторский текст, который печатается, "Нет". Я пытался возиться с использованием вариантов, как показано ниже, но это приводит к сбою моей программы.

authortext=a[0].nodeValue

Правильный вывод должен быть:

1
Bob
Nigel
2
Alice
Mary

Но то, что я получаю, это:

1
None
None
2
None
None

Любые предложения о том, как решить эту проблему?

5 ответов

Решение

Ваш authortext имеет тип 1 (ELEMENT_NODE), обычно нужно иметь TEXT_NODE чтобы получить строку. Это будет работать

a.childNodes[0].nodeValue

Узлы элемента не имеют значения nodeValue. Вы должны посмотреть на узлы Text внутри них. Если вы знаете, что внутри всегда есть один текстовый узел, вы можете сказать element.firstChild.data (данные такие же, как nodeValue для текстовых узлов).

Будьте осторожны: если нет текстового содержимого, не будет дочерних текстовых узлов и element.firstChild будет нулевым, вызывая .data доступ к сбою.

Быстрый способ получить содержимое прямых дочерних текстовых узлов:

text= ''.join(child.data for child in element.childNodes if child.nodeType==child.TEXT_NODE)

В DOM Level 3 Core вы получаете textContent свойство, которое вы можете использовать для рекурсивного получения текста внутри элемента, но minidom не поддерживает это (некоторые другие реализации Python DOM делают).

Быстрый доступ:

node.getElementsByTagName('author')[0].childNodes[0].nodeValue

Поскольку у вас всегда есть одно значение текстовых данных на автора, вы можете использовать element.firstChild.data

dom = parseString(document)
conferences = dom.getElementsByTagName("conference")

# Each conference here is a node
for conference in conferences:
    conference_name = conference.getAttribute("name")
    print 
    print conference_name.upper() + " - "

    authors = conference.getElementsByTagName("author")
    for author in authors:
        print "  ", author.firstChild.data
    # for

    print

Я немного поиграл с этим, и вот что я получил на работу:

# ...
authortext= a.childNodes[0].nodeValue
print authortext

приводя к выводу:

C: \ Temp\ ру>xml2.py
1
боб
Найджел
2
Алиса
Мэри

Я не могу сказать вам точно, почему вы должны получить доступ к childNode, чтобы получить внутренний текст, но по крайней мере это то, что вы искали.

Другие вопросы по тегам