XQuery concat没有以预期的方式输出文档XML

时间:2013-07-25 10:39:21

标签: xquery marklogic

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

return concat('let $d := 

', $d)

返回

let $d :=

bar

我需要它返回:

let $d :=

<foo>bar</foo>

3 个答案:

答案 0 :(得分: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传递XML。出于正确性,性能和安全性原因,此作业的正确工具是外部变量。

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:-2)

let $d := xdmp:quote(doc('foo.xml'))

return concat('let $d := &#xD;&#xD;', $d)