我正在尝试处理一堆 XML 文件,并在满足某些条件时向特定元素添加某些属性。我有相同 XML 文档的不同版本。其中一些有一些标签用于提供格式信息。这是一个例子:
<tok id="w-47692" ord="96" lemma="bové" xpos="VMIP3S0">Bové</tok>
<space/>
<add>
<tok form="Bernadó" id="w-47693" ord="97" lemma="bernadó" xpos="NP00000">Bernadó</tok>
</add>
<add>
<tok id="w-47694" ord="98" lemma="mayor" xpos="NCMS000">Mayor</tok>
</add>
<tok id="w-47695" ord="99" lemma="ferran" xpos="NP00000">Ferran</tok>
标签
<space/>
表示原始文档(XML 文档是其表示形式)有一个空格。标签<add> </add>
表明这些标签之间出现的内容不是原稿的一部分。 XML 文档的其他版本已清除这些格式元素:
<tok form="Bernadó" id="w-47693" ord="97" lemma="bernadó" xpos="NP00000">Bernadó</tok>
<tok id="w-47694" ord="98" lemma="mayor" xpos="NCMS000">Mayor</tok>
<tok id="w-47695" ord="99" lemma="ferran" xpos="NP00000">Ferran</tok>
我遇到的问题是脚本在处理两个文档时产生不同的结果。这是两个输出:
<add>
<tok form="Bernadó" id="w-47693" ord="97" lemma="bernadó" xpos="NP00000">Bernadó</tok>
</add>
<add>
<tok id="w-47694" ord="98" lemma="mayor" xpos="NCMS000">Mayor</tok>
</add>
<tok form="Bernadó" id="w-47693" ord="97" lemma="bernadó" xpos="NP0000">Bernadó</tok>
<tok form="Mayor" id="w-47694" ord="98" lemma="Major" xpos="NP0000">Mayor</tok>
我没有包含我正在使用的整个脚本,因为它相当复杂,但这是脚本相关部分的简化版本:
def fix_matching_toks(tok):
"""
Fix matching tokens by setting their lemma and xpos attributes.
"""
preceding_tok = tok.xpath("preceding-sibling::tok[1]")
if preceding_tok:
preceding_tok_last_dtok = preceding_tok[0].xpath("./dtok[last()]")
else:
preceding_tok_last_dtok = None
if tok.tag == "tok":
if preceding_tok and preceding_tok[0].get("xpos") is not None and preceding_tok[0].get("xpos", "").startswith("NP"):
tok.set("lemma", "Major")
tok.set("xpos", "NP00000")
在我看来,发生的情况是相关 tok 元素周围的标签阻止 XPath 表达式与预期元素匹配。我认为 XPath 表达式
xpath("preceding-sibling::tok[1]")
会匹配前面的 tok 元素,无论是否有元素介入,但很明显事实并非如此。
如何防止这种情况发生?我希望所有 XML 文档都以相同的方式进行处理,无论它们是否包含这些介入的“无关”元素。
我在 XPath 中看到 2 选项:
简单一个(但可能更慢):
preceding::tok[1]
复杂一个(但可能更快)
parent::add/preceding-sibling::*[1][self::add[tok]]/tok
| parent::add/preceding-sibling::*[1][self::tok]
| preceding-sibling::*[1][self::add[tok]]/tok
| preceding-sibling::*[1][self::tok]