2014-09-22 61 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

您可能需要通过绑定前缀(如“w”)来告诉它使用URI为“http://schemas.openxmlformats.org/wordprocessingml/2006/main”的命名空间。 – LarsH 2014-09-22 05:51:38

+0

是的,我已经这样做了,甚至通过'p'标签和't'标签提取所有文本。 – 2014-09-22 05:53:57

+0

请告诉我们您已经完成了什么。你展示的Python没有表明任何名称空间的使用。 – LarsH 2014-09-22 05:54:55

回答

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

表达式中的3210选择当前节点的父节点。因此,{...}i/../..将选择i节点的父 - 母节点。

+0

感谢它的工作!只是一个问题,XPath看起来有点硬编码(也许我错了)。这会提取文本中任何子元素或元素下的“我”吗? – 2014-09-25 08:36:17

+0

多数民众赞成在真棒,它按预期工作,可悲的是我只能upvote一次与我的个人资料:P – 2014-09-25 08:45:15

+0

@Swordy,我不擅长的文件格式;我的回答是针对你在问题中给出的xml。如果您向我展示另一个具有不同格式的示例,我可以给您更通用的解决方案。 – falsetru 2014-09-25 08:47:47

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>,那么你也知道下一行提取所有<w:t>节点来自匹配的<w:p>节点的文本。

+0

文件“”,行未知SyntaxError:无效的谓词 – 2014-09-22 10:58:36

+0

我想xpath会在这个更好。 – 2014-09-22 11:24:16

+0

对不起,我没有得到你,你提到的文件''在哪里?上面代码中'findall()'方法的参数是XPath ... – har07 2014-09-22 11:55:54