2014-09-26 73 views
1

我想提取带删除线的单词,即<w:delText>标签。我已经使用了一个表达式,并且成功地将其提取出来,除了某些单词出现中断。例如,单词"They"显示为'T''hey'。下面给出的是哪里的问题仍然存在一个xml样本:文本提取中的单词分隔符,Lxml Xpath

<w:delText 
    xml:space="preserve">. 
    </w:delText></w:r><w:r 
    w:rsidR="0020338C" 
    w:rsidDel="00147CFE"><w:rPr><w:rFonts 
    w:ascii="Times 
    New 
    Roman" 
    w:hAnsi="Times 
    New 
    Roman"/><w:sz 
    w:val="24"/></w:rPr><w:delText>T</w:delText></w:r><w:r 
    w:rsidR="00DF6A7D" 
    w:rsidDel="00147CFE"><w:rPr><w:rFonts 
    w:ascii="Times 
    New 
    Roman" 
    w:hAnsi="Times 
    New 
    Roman"/><w:sz 
    w:val="24"/></w:rPr><w:delText>hey</w:delText></w:r></w:del><w:ins 
    w:id="5" 
    w:author="Author" 
    w:date="2014-08-13T10:08:00Z"><w:r 
    w:rsidR="00147CFE"><w:rPr><w:rFonts 
    w:ascii="Times 
    New 
    Roman" 
    w:hAnsi="Times 
    New 
    Roman"/><w:sz 
    w:val="24"/></w:rPr><w:t 
    xml:space="preserve"> 
    that 
    helps 
    them</w:t></w:r></w:ins> 

我用下面的代码:

find = etree.XPath("//w:p//.//*[local-name() = 'delText']//text()" ,namespaces={'w':"http://schemas.openxmlformats.org/wordprocessingml/2006/main"}) 
list_of_deleted_words = (find(lxml_tree)) 

我怎么可能解决这一问题?

编辑

我意识到这个问题是只用言语是在他们大写字母,如“她”的话,“他”还可以获得分裂。

+1

那么,'delText'在概念上并不知道“单词”。您可以删除任何一段文本,包括空格。所以,试图找到提取的单词实际上是没有意义的。除非你确信只有完整的单词被删除? – 2014-09-26 11:29:46

+0

单词的部分也可以被删除,并且提取得很好。但在上述情况下,已删除单词“他们”。它为什么单独出现标记是另一个OOXML神秘-_- – 2014-09-26 11:34:48

+0

您的目标是提取**单词**(不管用户是否一次删除它们一个整个单词),还是您的目标是提取大块该用户删除? – LarsH 2014-09-26 14:33:30

回答

2

这就是“他们”应该算作一个字而不是两个(我的代码目前正在这样做)。

问题出现是因为文本的延伸被任意地放入了几个所谓的“运行”中。在OOXML,文字在w:p元素(段)像这样(简化结构)主办:

<w:p> 
    <w:r> 
    <w:t>Simpli</w:t> 
    </w:r> 
    <w:r> 
    <w:t>fied structures</w:t> 
    </w:r> 
</w:p> 

正如你所看到的,实际的文本里面w:t元素依次一个w:r元素中或“运行”。不幸的是,这种在单独运行中的分工非常随意,它可能只是任意的。据我所知,没有人知道如何选择开始新的跑步。

现在,转向您的问题,w:delText也在里面运行。而且,在那里,进入奔跑的碎片似乎纯粹是无用的。

用你目前的方法,没有办法知道一个特定的w:delText的文本内容是否是一个完整的单词。为此,您必须考虑整个运行顺序,包括正常文本和包含已删除文本的顺序。

很可能这是行得通的,因为删除的文本仍处于删除位置的运行状态。显示的OpenXML 2003年,略有不同,但它并不重要:

<w:r> 
    <w:t>Normal Text before deletion </w:t> 
</w:r> 
<aml:annotation aml:id="0" 
       w:type="Word.Deletion" 
       aml:author="Mathias Müller" 
       aml:createdate="2014-09-26T22:25:00Z"> 
    <aml:content> 
    <w:r wsp:rsidDel="00F647B7"> 
     <w:delText>T</w:delText> 
    </w:r> 
    </aml:content> 
</aml:annotation> 
<aml:annotation aml:id="1" 
       w:type="Word.Deletion" 
       aml:author="Mathias Müller" 
       aml:createdate="2014-09-26T22:24:00Z"> 
    <aml:content> 
    <w:r wsp:rsidDel="00F647B7"> 
     <w:delText>hey </w:delText> 
    </w:r> 
    </aml:content> 
</aml:annotation> 
<w:r> 
    <w:t>Normal Text after deletion </w:t> 
</w:r> 

换句话说,

  • 如果有两个“删除奔跑”在一排(或更多),在没有空格他们中的任何一个,那么你就知道他们只是一个词的部分。

至于字边界,

  • 如果被删除的运行是由一正常运行之前,它们之间具有空白(无论是在正常运行结束或删除的运行的开始)您知道删除的运行开始了一个新单词
  • 如果删除的运行前面是没有任何空格的正常运行,那么您应该断定该单词只有一部分被删除,并且该删除的运行不是整个单词
  • 上述所有情况对于已删除的运行是一回事之后是正常运行,两者之间有或没有空白。

当然,我们都知道,依靠空格来区分单词是一种粗糙的方法,但在这种情况下它可能就足够了。

+0

是的,现在我正在考虑在连续运行实例上使用类似于正则表达式的东西..任何建议从你的角度出发? – 2014-09-27 04:15:21

+0

@Swordy XSLT将非常适合这项任务(复杂的XML操作)。但是如果你对XSLT感到不舒服,我相信lxml和Python也是一个不错的选择。我认为正则表达式不会做到这一点,它必须是几个XPath表达式和条件(以我描述的方式)。但评论部分并不是真正的答案。尝试写一个新版本,并发布一个新问题,如果它不起作用。 – 2014-09-27 14:01:01

+0

ohk我会试试,可以发布链接,其中有xslt的例子,除了正式的lxml网站。我准备好学习xslt,如果这是一个更好的选择做上述.. – 2014-09-28 09:18:30

相关问题