x查询 "Content for update is empty"

xquery "Content for update is empty"

这是我第一次 运行 进入 Xquery (3.1) 错误 Content for update is empty 并且搜索 Google return 没有任何用处。

如果我运行这个简单的查询来识别嵌套/tei:p/tei:p:

for $x in $mycollection//tei:p/tei:p
return $x

我得到 XML 如下片段:

<p xmlns="http://www.tei-c.org/ns/1.0"/>
<p xmlns="http://www.tei-c.org/ns/1.0">Histoires qui sont maintenant du passé (Konjaku monogatari shū). Traduction, introduction et
commentaires de Bernard Frank, Paris, Gallimard/UNESCO, 1987 [1re éd. 1968] (Connaissance de
l'Orient, Série japonaise, 17), p. 323. </p>
<p xmlns="http://www.tei-c.org/ns/1.0">Ed. Chavannes, Cinq cents contes et apologues extraits du Tripitaka chinois, Paris, t. 4,
1934, Notes complémentaires..., p. 147.</p>
<p xmlns="http://www.tei-c.org/ns/1.0"/>
<p xmlns="http://www.tei-c.org/ns/1.0">Ed. Chavannes, Cinq cents contes et apologues extraits du Tripitaka chinois, Paris, t. 4,
1934, Notes complémentaires..., p. 129.</p>

即一些 text() 和其他 empty

我正在尝试 "de-duplicate" /tei:p/tei:p,但以下尝试 return 与上述相同的错误:

for $x in $mycollection//tei:p/tei:p
return update replace $x with $x/(text()|*)


for $x in $mycollection//tei:p/tei:p
let $y := $x/(text()|*)
return update replace $x with $y

我不明白为了更正查询而试图告诉我的错误是什么。

非常非常感谢。

编辑:

for $x in $mycollection//tei:p[tei:p and count(node()) eq 1]
let $y := $x/tei:p
return update replace $x with $y

我也试过了,用self轴替换了parent,导致了一个非常模糊的错误exerr:ERROR node not found:

for $x in $mycollection//tei:p/tei:p
let $y := $x/self::*
return update replace $x/parent::* with $y

解决方案:

for $x in $local:COLLECTIONS//tei:p/tei:p
return if ($x/(text()|*))
        then update replace $x with $x/(text()|*)
        else update delete $x

错误信息表明$y是一个空序列。 XQuery Update documentation描述replace语句如下:

update replace expr with exprSingle

Replaces the nodes returned by expr with the nodes in exprSingle. expr must evaluate to a single element, attribute, or text node. If it is an element, exprSingle must contain a single element node...

在某些情况下,如上面的示例数据所示,$y 会 return 一个空序列 - 这将违反 expr 必须计算为单个元素的规则。

要解决这种情况,您可以添加条件表达式,其中 else 子句为空序列 () 或删除语句:

if ($y instance of element()) then 
    update replace $x with $y
else 
    update delete $x

如果您的目标不仅仅是解决错误,而是找到更直接的解决方案来替换 "double-nested" 元素,例如:

<p><p>Mixed <hi>content</hi>.</p></p>

.. 与:

<p>Mixed <hi>content</hi>.</p>

...我建议这个查询,它注意不要无意中删除可能以某种方式滑入两个嵌套 <p> 元素之间的节点:

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";

for $x in $mycollection//tei:p[tei:p and count(node()) eq 1]
let $y := $x/tei:p
return
    update replace $x with $y

给定一个 $mycollection 这样的:

<text xmlns="http://www.tei-c.org/ns/1.0">
    <p>Hello</p>
    <p><p>Hello there</p></p>
    <p>Hello <p>there</p></p>
</text>

查询会将集合转换为如下形式:

<text xmlns="http://www.tei-c.org/ns/1.0">
    <p>Hello</p>
    <p>Hello there</p>
    <p>Hello <p>there</p></p>
</text>

这是查询的预期结果,因为只有第二个 <p> 元素有嵌套的 <p> 可以被干净地剥离。显然,如果您可以假设您的内容满足更简单的模式,则可以删除 and count(node()) eq 1 条件。