Чтение 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, что распечатывается нет."Я пытался возиться с использованием вариаций, таких как то, что ниже, но это заставляет мою программу ломаться.

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. Вы должны посмотреть на текстовые узлы внутри них. Если вы знаете, что внутри всегда есть один текстовый узел, вы можете сказать element.firstChild.data (данные такие же, как nodevalue для текстовых узлов).

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

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

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

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


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

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

поскольку у вас всегда есть одно значение текстовых данных для каждого автора, вы можете использовать элемент.возвращение null.данные

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\py>xml2.py
1
Bob
Nigel
2
Alice
Mary

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