在BaseX中如何将字符串转换为可用的XPath表达式?
如何将字符串转换为可执行的XPath表达式?
你当前的代码问题在于,$ti是字符串形式的路径,直接用来和$tiValue做比较只是在进行字符串匹配,而非定位到XML节点后取其值再比较。要实现字符串到XPath的转换,有两种常见方案:
方案1:使用动态执行函数(快速实现)
如果你的XQuery处理器支持eval()函数(比如eXist-db,从db:open判断你大概率在用这个),可以直接用它将字符串路径转为可执行的XPath表达式:
let $ti := "item/title" let $tiValue := "Welcome to America" return db:open('test')/*[eval($ti) = $tiValue]/base-uri()
这里eval($ti)会把字符串"item/title"解析为XPath路径,获取当前节点下对应路径的节点值,再和$tiValue做比较。
注意
这种方式存在XPath注入风险,如果$ti来自不可信的用户输入,可能会被注入恶意代码,只建议在可控输入场景下使用。
方案2:手动解析路径(安全可靠)
如果要避免注入风险,可以手动拆分路径字符串,递归遍历节点来定位目标:
declare function local:resolve-path($node as node(), $path as xs:string) as node()* { let $steps := tokenize($path, '/') return fold-left($steps, $node, function($current, $step) { $current/*[local-name() = $step] }) }; let $ti := "item/title" let $tiValue := "Welcome to America" return db:open('test')/*[local:resolve-path(., $ti) = $tiValue]/base-uri()
这个自定义函数local:resolve-path会把路径按/拆分,然后从当前节点开始一步步遍历到目标节点,全程不需要动态执行代码,安全性更高。
内容的提问来源于stack exchange,提问作者Dharmendra Kumar Singh
相关产品推荐
相关产品推荐

