【问题标题】:Word Breaks in text extraction , Lxml Xpath文本提取中的分词,Lxml Xpath
【发布时间】:2014-09-26 10:13:36
【问题描述】:

我想提取带有删除线的单词,即带有<w:delText> 标签的单词。我使用了一个表达式,它成功地提取了它,只是有些单词出现了损坏。例如,单词 "They" 显示为 'T''hey' 。下面给出了一个问题仍然存在的 xml 示例:

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

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

编辑

我意识到问题仅在于其中包含大写字母的单词,诸如“She”、“He”之类的单词也会被拆分。

【问题讨论】:

  • 好吧,从概念上讲,delText 不知道“单词”。您可以删除任何一段文本,包括空格。因此,试图找到提取的单词实际上是没有意义的。除非你很确定只删除完整的单词?
  • 部分词也可以删除,提取的很好。但在上述案例中,“他们”这个词被删除了。为什么它出现在单独的 标记中是另一个 OOXML 之谜-_-
  • 您的目标是提取单词(无论用户是否一次删除一个完整的单词),还是您的目标是提取用户删除的块?
  • 是单词.." 他们" 应该算作一个单词而不是两个(我的代码目前正在这样做)..

标签: python xml xpath lxml openxml


【解决方案1】:

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

问题的出现是因为文本段被任意放入几个所谓的“运行”中。在 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:telements 中,而 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>

换一种说法,

  • 如果连续有两个“已删除运行”(或更多),其中任何一个都没有空格,那么您知道它们只是一个单词的一部分。

至于词的边界,

  • 如果删除的运行之前是正常运行,它们之间有一个空格(在正常运行的结尾或已删除运行的开头),您知道删除的运行开始了一个新单词
  • 如果删除的运行之前是没有任何空格的正常运行,那么您应该得出结论,只有单词的一部分被删除,并且这个删除的运行不是整个单词
  • 对于已删除的运行,随后的正常运行(无论是否有空格),上述所有情况反之亦然。

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

【讨论】:

  • 是的,现在我正在考虑在连续运行实例上使用正则表达式之类的东西。你有什么建议吗?
  • @Swordy XSLT 非常适合该任务(复杂的 XML 操作)。但如果您对 XSLT 不满意,我相信 lxml 和 Python 也是不错的选择。我不认为正则表达式会起作用,它必须是几个 XPath 表达式和条件(以我描述的方式)。但是 cmets 部分并不是真正回答这个问题的地方。尝试编写一个新版本并发布一个新问题,如果它不起作用。
  • 哦,我会试试的,你能发一个链接,里面有 xslt 的例子,除了官方的 lxml 网站。如果执行上述操作是一个更好的选择,我已经准备好学习 xslt..
  • @Swordy 我可以推荐的网站是:ibm.com/developerworks/xml/tutorials/x-introxslt/…。它需要一些其他编程语言的知识,但这对你来说应该不是问题。
  • 谢谢@mathias,我会研究整个事情,如果我对这种方法有疑问,我会在这里问,如果我创建的代码不起作用,我会链接我的新问题在这里.. :)
猜你喜欢
  • 2018-01-02
  • 2011-07-31
  • 1970-01-01
  • 2022-01-23
  • 2017-08-05
  • 2018-11-12
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
相关资源
最近更新 更多