如何在xquery中更新除node-replace之外的值?我有一个名为title的元素,它是空的,我应该将值更新为“submitted”。示例文件:
<books>
<title></title>
</books>
发布于 2021-06-16 14:55:18
我假设您是在请求xdmp:node-replace()
的替代品,因为这个XML文档是内存中的对象,而不是(还没有)持久化文档?
您可以执行recursive descent typeswitch
xquery version "1.0-ml";
(: This is the recursive typeswitch function :)
declare function local:transform($nodes as node()*) as node()*
{
for $n in $nodes return
typeswitch ($n)
case text() return $n
case attribute() return $n
case comment() return $n
case processing-instruction() return $n
case element (title) return <title>submitted</title>
default return element {$n/name()} {local:transform($n/(@*|node()))}
};
let $books :=
<books foo="x"><!--test--><?PITarget PIContent?>
<title></title>
</books>
return
local:transform($books)
,但我发现这很乏味,如果你最终需要更复杂的转换场景,就不喜欢通用的转换。
对于XQuery中更复杂的内存中XML结构的转换,我会考虑使用Ryan Dew的XQuery XML Memory Operations库:
import module namespace mem = "http://maxdewpoint.blogspot.com/memory-operations"
at "/memory-operations.xqy";
let $books :=
<books>
<title></title>
</books>
return
mem:copy(fn:root($books)) ! (
mem:replace(., $books/title, element title {"submitted"}),
mem:execute(.)
)
在转换XML时(无论是在内存中还是在数据库中的文档),我更喜欢XSLT。您可以使用xdmp:xslt-invoke()
(带有已安装的样式表)或xdmp:xslt-eval()
xquery version "1.0-ml";
let $xslt :=
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="title">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:text>submitted</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
let $books :=
<books>
<title></title>
</books>
return xdmp:xslt-eval($xslt, $books)
https://stackoverflow.com/questions/68004115
复制相似问题