2014-09-22 4 views
1

У меня есть этот текст:Извлечение текста с LXML

INTRODUCTION 
This is a test document for xml. 
I need to extract this sentence. 

Conclusion 
It should hopefully.. 

Линия I need to extract this sentence. курсивом. XML файла выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n 
<w:document 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
    mc:Ignorable="w14 w15 wp14"> 
    <w:body> 
     <w:p w:rsidR="00470EEF" w:rsidRDefault="00456755"> 
     <w:pPr> 
      <w:rPr> 
       <w:b/> 
      </w:rPr> 
     </w:pPr> 
     <w:r w:rsidRPr="00456755"> 
      <w:rPr> 
       <w:b/> 
      </w:rPr> 
      <w:t>INTRODUCTION</w:t> 
     </w:r> 
     </w:p> 
     <w:p w:rsidR="00456755" w:rsidRPr="00B042E3" w:rsidRDefault="00456755"> 
     <w:pPr> 
      <w:rPr> 
       <w:color w:val="FFFF00"/> 
      </w:rPr> 
     </w:pPr> 
     <w:r w:rsidRPr="00B042E3"> 
      <w:rPr> 
       <w:color w:val="FFFF00"/> 
      </w:rPr> 
      <w:t>This is a test document for xml.</w:t> 
     </w:r> 
     </w:p> 
     <w:p w:rsidR="00456755" w:rsidRDefault="00E971E1"> 
     <w:r> 
      <w:rPr> 
       <w:i/> 
      </w:rPr> 
      <w:t>I need to extract this sentence.</w:t> 
     </w:r> 
     <w:bookmarkStart w:id="0" w:name="_GoBack"/> 
     <w:bookmarkEnd w:id="0"/> 
     </w:p> 
     <w:p w:rsidR="00456755" w:rsidRDefault="00456755"/> 
     <w:p w:rsidR="00456755" w:rsidRDefault="00456755"> 
     <w:pPr> 
      <w:rPr> 
       <w:b/> 
      </w:rPr> 
     </w:pPr> 
     <w:r w:rsidRPr="00456755"> 
      <w:rPr> 
       <w:b/> 
      </w:rPr> 
      <w:t>Conclusion</w:t> 
     </w:r> 
     </w:p> 
     <w:p w:rsidR="00456755" w:rsidRPr="00456755" w:rsidRDefault="00456755"> 
     <w:r w:rsidRPr="00456755"> 
      <w:t>It should hopefully</w:t> 
     </w:r> 
     <w:r> 
      <w:t>..</w:t> 
     </w:r> 
     </w:p> 
     <w:sectPr w:rsidR="00456755" w:rsidRPr="00456755"> 
     <w:pgSz w:w="11906" w:h="16838"/> 
     <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/> 
     <w:cols w:space="708"/> 
     <w:docGrid w:linePitch="360"/> 
     </w:sectPr> 
    </w:body> 
</w:document> 

Я пробовал:

tree = ET.parse(doc_xml) 
[b.tag for b in tree.iterfind(".//i")] 

Вышеприведенные возвращает пустой список.

Я много искал, но не смог понять, как это сделать, поскольку текст содержится в пределах <w:i/>. Я видел это question, где это было сделано легко с помощью BeautifulSoup.

Редактировать: Это не относится точно, но это подход ElementTree для извлечения всего текста.

w = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' 
    for p in source.findall('.//{' + w + '}p'): 
     print ''.join(t.text for t in p.findall('.//{' + w + '}t')) 
+0

Возможно, вам потребуется указать пространство имен, URI которого «http://schemas.openxmlformats.org/wordprocessingml/2006/main», привязывая к нему префикс, такой как 'w'. – LarsH

+0

Да, я уже сделал это и даже извлек весь текст тегами «p» и «t». –

+0

Пожалуйста, покажите нам, что вы сделали. Python, который вы показали, не указывает на использование пространств имен. – LarsH

ответ

2

Слегка модифицируя вы получите то, что вы хотите:

>>> w = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'  
>>> for t in tree.findall('.//{%(ns)s}i/../..//{%(ns)s}t' % {'ns': w}): 
...  print t.text 
... 
I need to extract this sentence. 

Кстати, если вы используете local-name(), вам не нужно указать пространство имен (нужно использовать xpath метод, который доступен в lxml):

>>> for t in tree.xpath('.//*[local-name()="i"]/../..//*[local-name()="t"]'): 
...  print t.text 
... 
I need to extract this sentence. 

UPDATE

.. в выражении выбирает родительский узел текущего узла. Таким образом, {...}i/../.. выберет grand-parent node узла i.

+0

спасибо, что это сработало !! Просто вопрос, xpath выглядит немного жестко закодированным (возможно, я ошибаюсь). Будет ли этот экстракт «i» попадать под любой элемент или элемент в тексте? –

+0

thats awesome, он работает по назначению, к сожалению, я могу только один раз увеличить свой профиль: P –

+0

@Swordy, я плохо разбираюсь в формате файла; мой ответ специфичен для xml, который вы дали в вопросе. Если вы покажете мне другой пример, который имеет другой формат, я могу дать вам более общее решение. – falsetru

2

Строительство моего ответа основан на коде в Edit разделе:

w = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' 
for p in source.findall('.//{' + w + '}p[.//{' + w + '}i]'): 
    print ''.join(t.text for t in p.findall('.//{' + w + '}t')) 

В принципе, первый XPath должен соответствовать всем <w:p> элементам, имеющим потомка узла <w:i>, то, как вы знаете, следующий экстракт линии всем <w:t> Узлы текста из сопоставленных <w:p> узлов.

+0

Файл «», строка неизвестна СинтаксисError: недопустимый предикат –

+0

Я предполагаю, что xpath будет лучше на этом. –

+0

Извините, я не получил вас, где находится файл '', о котором вы упомянули? Параметр 'findall()' методов в приведенном выше коде XPath ... – har07

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