Xquery 如何有效地替换XML的多个节点?

Xquery 如何有效地替换XML的多个节点?,xquery,marklogic,Xquery,Marklogic,我正试图在一个文档中一次性替换大约500个节点,我的数据库中有5000多个文档 我正在使用的代码与我之前提出的这个问题有关- 任何提高代码效率的建议?通常应避免使用内存更新库,尤其是在对同一文档进行多次方法调用时。由于每个方法都遍历整个节点树并生成一个全新的文档,因此,如果您运行大型文档和/或对这些文档进行大量mem:*方法调用,则速度可能会很慢,成本也会很高 更好的替代者是Ryan Dew,或者使用XSLT 下面是一个示例,说明如何使用XSLT执行这种“合并”,这种“合并”应该比使用内存更新

我正试图在一个文档中一次性替换大约500个节点,我的数据库中有5000多个文档

我正在使用的代码与我之前提出的这个问题有关-


任何提高代码效率的建议?

通常应避免使用内存更新库,尤其是在对同一文档进行多次方法调用时。由于每个方法都遍历整个节点树并生成一个全新的文档,因此,如果您运行大型文档和/或对这些文档进行大量mem:*方法调用,则速度可能会很慢,成本也会很高

更好的替代者是Ryan Dew,或者使用XSLT

下面是一个示例,说明如何使用XSLT执行这种“合并”,这种“合并”应该比使用内存更新方法更好:

declare variable $STAGING := document{
<root>
 <ID>1</ID>
 <value1>India</value1>
 <value2>USA</value2>
 <value3>Russia</value3>
 <value4>Srilanka</value4>
 <value5>Europe</value5>
 <value6>Antartica</value6>
 <value7>Spain</value7>
</root>
};

declare variable $FINAL := document{
<root>
 <ID>1</ID>
 <value1></value1>
 <value2></value2>
 <value3></value3>
 <value4></value4>
 <value5>Europe</value5>
 <value6>Antartica</value6>
</root>
};

declare variable $XSLT := 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:param name="staging-doc"/>
  <xsl:param name="element-names"/>

  <xsl:variable name="final-doc" select="/"/>

  <xsl:key name="staging-elements" match="root/*[local-name() = $element-names]" use="local-name()"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="root/*[local-name() = $element-names]">
    <!--if there is an element in the staging-elements doc with this name, use it. Otherwise, use the matched element from this doc -->
    <xsl:copy-of select="(key('staging-elements', local-name(.), $staging-doc), .)[1]"/>
  </xsl:template>

  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <!-- also copy any other elements with the specified names from the staging document that were not already in the final -->
      <xsl:apply-templates select="$staging-doc/root/*[local-name() = $element-names and not(key('staging-elements', local-name(), $final-doc))]"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>;

declare variable $PARAMS := map:new((
    map:entry("staging-doc", $STAGING), 
    map:entry("element-names", tokenize(("value1,value2,value3,value4,value7"), ",") )
  ));

xdmp:xslt-eval($XSLT, $FINAL, $PARAMS)
声明变量$STAGING:=文档{
1.
印度
美国
俄罗斯
斯利兰卡
欧洲
南极洲
西班牙
};
声明变量$FINAL:=文档{
1.
欧洲
南极洲
};
声明变量$XSLT:=
;
声明变量$PARAMS:=map:new((
映射:条目(“暂存单据”,“暂存美元”),
映射:条目(“元素名称”,标记化((“value1,value2,value3,value4,value7”),“,”)
));
xdmp:xslt eval($xslt,$FINAL,$PARAMS)

@Mads——非常感谢。它是否也需要
xdmp:documentinsert()
?或者它会自动将所有文档替换到DB中?是的,您需要保存结果(在代码中有条件地在if($boolean)中设置$envelope的部分中使用,而不是使用in-mem函数)@Mads——非常感谢:),这很有帮助。