如何在FontoXPath中通过动态XPath选择节点并执行插入操作?
如何在FontoXPath中通过动态XPath选择节点并执行插入操作?
问题描述
我刚接触FontoXPath和XQuery,想实现这样的功能:先根据动态指定的XPath在文档中选中节点,然后执行插入操作。我写了如下代码:
declare %public %updating function xyz:change($bc as document-node(), $ch as element()) { let $contextNode := evaluateXPath($ch/@contextNode, $bc) return insert node $ch/element() as last into $contextNode };
这里的$ch/@contextNode是存储在属性中的一段XPath表达式。我试过把插入语句改成as last into $bc/changes/*[last()]时是能正常得到结果的,但问题出在evaluateXPath函数上——不管我尝试了哪些命名空间,始终会报错:
XPST0017: Function evaluateXPath with arity of 2 not registered.
想请教大家:在不添加额外依赖的情况下,用FontoXPath该怎么实现这个需求?或者是不是这个功能目前在FontoXPath里还没实现?
解决方案
其实你遇到问题的核心原因是:FontoXPath并没有内置evaluateXPath这个函数,这就是报错的根源。要实现动态执行XPath的需求,你可以使用FontoXPath官方提供的fontoxpath:evaluate函数,具体步骤如下:
- 绑定FontoXPath命名空间:首先需要在代码开头声明FontoXPath的命名空间,不然无法识别这个函数。
- 传入字符串类型的XPath:确保把
$ch/@contextNode转换成字符串传入evaluate函数,因为它的第一个参数要求是字符串形式的XPath表达式。
修改后的代码示例:
declare namespace fontoxpath = "http://fontoxml.com/fontoxpath"; declare %public %updating function xyz:change($bc as document-node(), $ch as element()) { let $contextNode := fontoxpath:evaluate($ch/@contextNode/string(), $bc) return insert node $ch/element() as last into $contextNode };
额外注意事项
如果你的动态XPath表达式涉及到自定义命名空间,还需要传递命名空间映射给evaluate函数的第三个参数,否则可能无法正确解析节点。示例如下:
declare namespace fontoxpath = "http://fontoxml.com/fontoxpath"; declare %public %updating function xyz:change($bc as document-node(), $ch as element()) { -- 定义命名空间映射,key是前缀,value是命名空间URI let $nsMapping := map { 'myNs': 'http://example.com/custom-namespace' } let $contextNode := fontoxpath:evaluate($ch/@contextNode/string(), $bc, $nsMapping) return insert node $ch/element() as last into $contextNode };
这个fontoxpath:evaluate是FontoXPath专门为动态求值场景提供的函数,只要你的FontoXPath版本不是太老旧,都应该支持这个功能哦。
备注:内容来源于stack exchange,提问作者Sander_P
相关产品推荐
相关产品推荐

