使用lxml提取文本

时间:2014-09-22 04:02:41

标签: python xml xpath lxml elementtree

我有这样的文字:

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'))

2 个答案:

答案 0 :(得分:2)

根据您在编辑部分中的代码构建我的答案:

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>元素,然后如您所知,下一行将从匹配的{{1}中提取所有<w:t>个节点的文本} nodes。

答案 1 :(得分: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.

<强>更新

表达式中的

..选择当前节点的父节点。因此,{...}i/../..将选择i节点的祖父节点。