2009-09-11 5 views
23

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

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

authortext=a[0].nodeValue 

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

1 
Bob 
Nigel 
2 
Alice 
Mary 

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

1 
None 
None 
2 
None 
None 

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

ответ

23

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

a.childNodes[0].nodeValue 
0

Я играл с ним немного, и вот что я должен работать:

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

приводит к выходу:

 
C:\temp\py>xml2.py 
1 
Bob 
Nigel 
2 
Alice 
Mary 

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

6

У узлов элемента нет nodeValue. Вы должны посмотреть на узлы Text внутри них. Если вы знаете, что внутри всегда есть один текстовый узел, вы можете сказать 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 вы получить textContent свойство можно использовать, чтобы получить текст внутри Элемента рекурсивно, но minidom не поддерживайте это (некоторые другие реализации DOM Python).

2

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

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

Поскольку у вас всегда есть одно значение данных текст каждого автора вы можете использовать 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