Чтение 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, чтобы получить внутренний текст, но по крайней мере это то, что вы искали.