2017-02-22 9 views
0

Я разбираю несколько больших xml-файлов с целью извлечь весь необработанный текст, содержащийся в элементе body. У меня нет субэлементов текста - я просто конкатенирую весь текст.lxml не извлекает весь текст, когда присутствуют вложенные элементы?

Соответствующий бит кода, я использую для достижения этой цели является:

# find all instances of `body` 
result = [] 
for body in tree.findall('.//{*}body'): 
    # iterate recursively over all sub-elemetns of `body` 
    for node in body.iter('*'): 
     # append any text if it exists 
     if node.text: 
      # handle the text 
      result.append(node.text.strip()) 
print(' '.join(result)) 

Довольно просто, и я подумал, он работал, но я нашел несколько случаев, когда это терпит неудачу, что я Я не знаю, как обойти. Вот минимальный пример извлекается из файла XML:

<cja:body> 
    <ce:sections xmlns:ce=".../xml/common/schema"> 
    <ce:para view="all">For scyptolin A or B the IC 
       <ce:inf loc="post">50</ce:inf> was erroneously calculated at 3.1 μg/ml. The correct IC 
       <ce:inf loc="post">50</ce:inf> was determined at 0.16 μg/ml for both scyptolins. 
      </ce:para> 
    </ce:sections> 
</cja:body> 

Если я запускаю выше блок кода на этом XML, вывод:

For scyptolin A or B the IC 50 50 

Так что проблема, для para узла, node.text только кажется, чтобы получить текст, который встречается до вложенный элемент inf. Как извлечь весь текст, а не только то, что происходит перед вложенными элементами? Чтобы было ясно, желаемый результат здесь будет:

For scyptolin A or B the IC 50 was erroneously calculated at 3.1 μg/ml. The correct IC 50 was determined at 0.16 μg/ml for both scyptolins. 
+0

А, похоже, я ищу атрибут '.tail', по [этому вопросу] (https://stackoverflow.com/questions/16701546/how-to-extract-text-in-nested-xml -after-закрывающаяся-оф-один-таг-в-питон-с помощью XML--е) – moustachio

ответ

0

Оказывается, это очень похоже на this question, но я отвечу здесь для полноты картины.

Оказывается, мне нужно использовать атрибут inf элемента .tail, чтобы получить текст после его (который был сюрприз ... Я думал, что текст все равно будет атрибутом para элемента). Таким образом, фиксированный код будет:

result = [] 
for body in tree.findall('.//{*}body'): 
    # iterate recursively over all sub-elemetns of `body` 
    for node in body.iter('*'): 
     # append any text if it exists 
     if node.text: 
      result.append(node.text.strip()) 
     # NEW! add `node.tail` if present: 
     if node.tail: 
      result.append(node.tail.strip()) 
print(' '.join(result)) 

Что дает

For scyptolin A or B the IC 50 was erroneously calculated at 3.1 μg/ml. The correct IC 50 was determined at 0.16 μg/ml for both scyptolins. 

по желанию.

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