2015-07-31 2 views
1

У меня есть эти данные:Как получить элемент владельца текстового узла?

<data> 
    <foo>foo text</foo> 
    data text 
    <bar> 
     bar text 
     <baz>text</baz> 
     <baz>text</baz> 
     bar text 
    </bar> 
    data text 
</data> 

и мне нужно получить все текстовые значения в порядке, изменить текст внутри «БАЗ» метки и печати. Мой код:

text = [] 
for element in etree.xpath("./*"): 
    text.extend(element.xpath("./text()")) 
    if element.tag == 'bar': 
     text.extend(["baz " + s for s in element.xpath("./baz/text()")]) 
print '\n'.join([s.strip() for s in text if s.strip()]) 

выход:

foo text 
bar text 
bar text 
baz text 
baz text 

, но мне нужно:

foo text 
data text 
bar text 
baz text 
baz text 
bar text 
data text 

Как я могу получить text() узла в порядке и без потерянной data text текста?

Редактировать Я знаю о etree.xpath(".//text()"), который может дать мне весь текст в порядке, но мне нужно изменить текст внутри тега baz. Это точка. Как получить значение тега для каждого элемента из .//text() XPath?

ответ

1

Предполагая, что вы используете lxml, вы можете вызвать getparent() функцию, чтобы получить владелец элемента текстового узла, например:

import lxml.etree 
etree = lxml.etree.fromstring(''' 
<data> 
    <foo>foo text</foo> 
    data text 
    <bar> 
     bar text 
     <baz>text</baz> 
     <baz>text</baz> 
     bar text 
    </bar> 
    data text 
</data> 
''') 

for text in etree.xpath("//text()[normalize-space()]"): 
    parenttag = text.getparent().tag 
    print(parenttag, text) 

выражения XPath //text()[normalize-space()] просто означает, что вернуть все непустые текстовые узлы в документе XML.

выход:

('foo', 'foo text') 
('foo', '\n data text\n ') 
('bar', '\n  bar text\n  ') 
('baz', 'text') 
('baz', 'text') 
('baz', '\n  bar text\n ') 
('bar', '\n data text\n') 
+0

Моя проблема решена, Тпх. Но у меня есть быстрый вопрос. Почему родительские теги для значений «текст данных» «foo» и «bar»? Я думаю, что это должен быть тег «data». Похоже, что это не родительский тег, только предыдущий –

+1

Полное объяснение этого поведения можно найти в http://stackoverflow.com/questions/31770189/why-getparent-dont-work-as-expected –

Смежные вопросы