【问题标题】:Annotating a text using a dictionary with Xquery and printing the whole result使用带有 Xquery 的字典注释文本并打印整个结果
【发布时间】:2012-09-26 08:58:50
【问题描述】:

我是 xquery 的初学者,希望您能帮我简单解释一下。我正在使用 BaseX 7.0.1。

我有一个如下所示的 dictionary.xml 文件:

<doc>
    <entry>
        <vedette>je</vedette>
        <variante>je</variante>
        <variante>j'</variante>
        <partiedudiscours>pronom</partiedudiscours>
    </entry>
</doc>

我还有另一个 malone_fr.xml 文件,其中包含我要注释的文本,如下所示:

<doc>
    L’Opportunité 
    Par : Walter Malone (1866-1915)
    Ils ont mal conclu ceux qui disent que je ne reviendrai plus
    Quand une fois j’ai frappé à ta porte et ne t’ai pas rencontré,
</doc>

所以我想将dictionary.xml 的 部分的内容与我的文本进行比较,并用 的内容标记文本。 到目前为止,我已经能够用这段代码做到这一点:

let $comp := data(for $j in tokenize(for $i in db:open('malone_fr')/doc return $i,"\n") 
return tokenize($j," "))
for $aa in $comp
return
for $lemme in db:open('dictionnaire')/doc/entry
return
let $oldName :=$aa
return
if ($oldName= $lemme/variante)
then 
let $newName := element  {$lemme/partiedudiscours}  {$aa}
return
for $bb in $comp
return
if ($bb=$oldName)
then $newName 
else ($bb)
else ()

这给了我以下结果: [第一次迭代]

L’Opportunité  Par : Walter Malone (1866-1915) Ils<verbe>ont</verbe> mal conclu ceux qui disent que je ne reviendrai plus

[第二次迭代]

L’Opportunité  Par : Walter Malone (1866-1915) <pronom>Ils</pronom>ont mal conclu ceux qui disent que je ne reviendrai plus

如您所见,它只显示每个单词的迭代结果,而我需要一个带有如下注释的整个文本的结果:

L’Opportunité  Par : Walter Malone (1866-1915) <pronom>Ils</pronom><verbe>ont</verbe> <adverbe>mal</adverbe> <verb>conclu</verb> 

等等。 我不知道如何处理 for 循环来做到这一点。

提前致谢。

【问题讨论】:

    标签: xml text xquery


    【解决方案1】:

    我认为您的解决方案比它需要的要复杂一些。您应该能够在一个循环中完成此操作。使用 XPath 执行查找 - 而不是显式循环遍历字典中的所有值 - 将使您的数据库能够优化以更快地检索字典数据。

    let $toks := data(
        for $i in db:open('malone_fr')/doc 
        return tokenize($i,"\s"))
    for $t in $toks
    return
        let $e := $dict/entry[variante = $t]    
        return
            if ($e)
            then (element { $e/partiedudiscours } { $t }, text{" "})
            else ($t, text{" "})
    

    此外,tokenize() 步骤会丢弃空格,因此您的输出序列中不存在空格。它只会出现间隔,因为这通常是呈现一系列原子类型的默认方法;但是,正如您从测试输出中看到的那样,空间不会在元素周围呈现。在上面的解决方案中,我添加了非常基本的空间处理,因此元素的间距也正确。如果不需要,您可以删除 text{" "} 节点。

    更新:添加了@DennisKnochenwefel 的建议

    【讨论】:

    • 不错的解决方案。只有一个潜在的改进: let $toks := data(tokenize(db:open('malone_fr')/doc,"\s"))
    • 或更好(tokenize 不适用于序列): let $toks := data(for $i in db:open('malone_fr')/doc return tokenize($i,"\s "))
    • @DennisKnochenwefel 谢谢,我更新了解决方案以包含您的建议。我对 BaseX 语法不太熟悉,所以出于谨慎,我没有弄乱标记化代码。
    • 非常感谢您的回答。 db:open('dictionnaire')//entry[variante = $t 中缺少一个斜杠,但它工作得很好!非常感谢!
    猜你喜欢
    • 2012-09-17
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2018-12-29
    相关资源
    最近更新 更多