2014-11-11 1 views
0

Учитывая элемент, как этотКак я могу перебирать дочерние текстовые узлы (а не потомки) в ElementTree?

<A> 
    hello 

    <annotation> NOT part of text </annotation> 

    world 
</A> 

, как я могу получить только ребенок текстовые узлы (например, XPath text()), используя ElementTree?

Оба iter() и itertext() являются пешеходными дорожками, которые включают в себя все узлы-потомки. Я не знаю, как это сделать. Плюс, iter() находит только элементов, так или иначе (в конце концов, ElementTree), поэтому не может использоваться для сбора текстовых узлов как таковых.

Я понимаю, что есть библиотека под названием lxml, которая обеспечивает лучшую поддержку XPath, но я спрашиваю здесь, прежде чем добавлять другую зависимость. (Плюс я очень новичок в Python, так что я, возможно, отсутствует что-то очевидное.)

ответ

1

Вы найдете текст вашего примера несколько противоинтуитивно в трех атрибутов:

  • A.text для «привет»
  • annotation.text для "не является частью текста"
  • annotation.tail для "мира"

(пробелы опущены). Это несколько громоздко. Однако, что-то в этом направлении должно помочь:

import xml.etree.ElementTree as et 

xml = """ 
<A> 
    hello 

    <annotation> NOT part of text </annotation> 

    world 
</A>""" 


doc = et.fromstring(xml) 


def all_texts(root): 
    if root.text is not None: 
     yield root.text 
    for child in root: 
     if child.tail is not None: 
      yield child.tail 


print list(all_texts(doc)) 
+0

Спасибо! Это прекрасно работает. У меня было ощущение, что здесь может быть использовано нечетное свойство 'tail'. – harpo