Saxon EE 9.9的XSLT3.0中,用saxon:compile-query合并节点集的更佳方案?
在Saxon EE 9.9的XSLT 3.0中传递多节点集给XQuery的优化方案
针对你遇到的saxon:query/saxon:compile-query仅支持原子值参数的问题,有以下几种更优方案:
1. 优先使用xsl:evaluate替代saxon:query
Saxon EE 9.9支持XSLT 3.0标准的xsl:evaluate函数,它允许直接传递节点集作为参数(参数类型支持item()*,而非仅限原子值),且可以指定运行XQuery表达式。这是最简洁高效的方案:
<!-- 定义两个目标节点集 --> <xsl:variable name="nodeset1" select="//some/nodes1"/> <xsl:variable name="nodeset2" select="//some/nodes2"/> <!-- XQuery表达式,直接引用外部变量 --> <xsl:variable name="xquery-code" select="'$set1 || $set2'"/> <!-- 调用xsl:evaluate传递节点集参数,指定语言为XQuery --> <xsl:variable name="merged-result" select=" xsl:evaluate( $xquery-code, map{'set1': $nodeset1, 'set2': $nodeset2}, map{'language': 'xquery'} ) "/>
2. 优化上下文项的打包方式
如果必须使用saxon:query,可以对现有打包方案做优化,通过命名子元素明确区分两个节点集,避免后续XQuery逻辑中需要靠位置判断节点归属:
<!-- 将两个节点集包裹到带命名子元素的上下文节点中 --> <xsl:variable name="combined-context" select=" element(combined){ element(set1){$nodeset1}, element(set2){$nodeset2} } "/> <!-- XQuery中直接通过子元素路径获取对应节点集 --> <xsl:variable name="merged-result" select=" saxon:query( '$context()/set1/node() || $context()/set2/node()', $combined-context ) "/>
3. 序列化+解析传递节点集
将第二个节点集序列化为XML字符串,作为原子值参数传入XQuery后解析还原,适合节点集结构不复杂的场景:
<!-- 序列化第二个节点集为字符串 --> <xsl:variable name="nodeset2-serialized" select="serialize($nodeset2)"/> <!-- 传递序列化后的字符串参数 --> <xsl:variable name="merged-result" select=" saxon:query( 'declare variable $nodeset2-str external; $context() || parse-xml($nodeset2-str)//node()', $nodeset1, map{'nodeset2-str': $nodeset2-serialized} ) "/>
其中方案1的xsl:evaluate是最优选择,无需额外的节点打包或序列化开销,且代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

