-1
let $d := doc('foo.xml')

return concat('let $d := 

', $d)

返回

let $d :=

bar

我需要它返回:

let $d :=

<foo>bar</foo>
4

3 回答 3

5

读取 的函数签名fn:concat,没有理由期望它输出 XML。来自http://www.w3.org/TR/xpath-functions/#func-concat

fn:concat(
  $arg1 as xs:anyAtomicType?,
  $arg2 as xs:anyAtomicType?,
  ...)
as xs:string

也就是说,它接受可变数量的原子项目并返回一个字符串。因此,如果您向它传递一个 XML 节点,它会尝试将其原子化并返回一个字符串结果。如果您还没有遇到雾化,请尝试string(doc($uri))看看会发生什么。

忽略这一点,您似乎正在尝试使用字符串操作构建 XQuery 表达式 - 可能与xdmp:eval? 这很好,但不要使用xdmp:quote. 出于正确性、性能和安全原因,这项工作的正确工具是外部变量。

xdmp:eval('
  declare variable $INPUT external ;
  let $d := $INPUT
  return xdmp:describe($d)',
  (xs:QName('INPUT'), $d))

更好的是,将字符串部分编写为单独的 XQuery 模块,xdmp:invoke并使用相同的外部变量参数。

为什么要这样做?正确性、效率和安全性。如果你养成了盲目评估字符串的习惯,那么你就是在为问题做准备。传递节点引用比引用大节点更有效。当您将 XML 作为字符串引用时,您最终可能会使用 XQuery 有效字符,例如{. 然后你必须逃避它们(或切换到 using xdmp:unquote,但这会降低效率)。任何转义都容易出错。在 SQL 中,处理此问题的经典方法是使用绑定变量,而对于 XQuery,它是一个外部变量。与 SQL 中的绑定变量一样,外部变量处理转义。这也使得注入攻击更加困难。

于 2013-07-25T15:23:12.470 回答
0

使用管道连接。例如: $a||$b 如果您的变量是原子类型,那么您可以使用字符串连接。例如:, $a||fn:string-join(($b),",")

于 2017-07-07T20:05:46.560 回答
-2
let $d := xdmp:quote(doc('foo.xml'))

return concat('let $d := &#xD;&#xD;', $d)
于 2013-07-25T11:23:59.143 回答