【问题标题】:Xquery get the children nodes by passing parent value at run timeXquery 通过在运行时传递父值来获取子节点
【发布时间】:2015-06-17 06:22:32
【问题描述】:

我需要在运行时传递一个值来获取所有子元素。

例如这是我的 XML:

<person>
   <details1>
      <name>jack</name>
      <age>26</age>
   </details1>
   <details2>
      <name>john</name>
      <age>48</age>
   </details2>
</person>

我的查询:

let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return $x/$y

所以我在这里期待结果

<details1>
<name>jack</name>
<age>26</age>
</details1>

但它返回与 $y 相同的名称,即“details1”
或者如果我这样查询

let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return $x//$y

结果将是“details1”12 次​​p>

我是 XQuery 新手,请帮助我解决问题

【问题讨论】:

    标签: xpath xquery marklogic


    【解决方案1】:

    您似乎尝试使用字符串$y 作为节点步骤。但是,在 XPath/XQuery 中,路径步骤不同于字符串,因此您不能简单地将字符串添加为路径步骤。相反,您可以查找所有要求它们具有相同名称的后代元素,即:

    let $y as xs:string := "details1"
    let $x := fn:doc(cts:uri-match('*person.xml'))
    return $x/*[name(.) = $y]
    

    【讨论】:

    • 使用name() 几乎总是一个坏主意。每次使用时,都应该考虑node-name(),有时甚至是local-name(),是不是更好)。
    【解决方案2】:

    正如 drkk 所说,您必须查看元素的名称。但是使用name() 是危险的。它返回元素的词法名称,如果元素有前缀,它可能是ns:elem。并且每个文档中的前缀都可以不同,即使对于相同的命名空间也是如此。所以要么你只匹配本地名称:

    let $y as xs:string := 'details1'
    let $x := fn:doc(cts:uri-match('*person.xml'))
    return
       $x/*[local-name(.) eq $y]
    

    或者更好的是,匹配一个 QName(注意 node-name() 的用法):

    let $y as xs:string := xs:QName('details1')
    let $x := fn:doc(cts:uri-match('*person.xml'))
    return
       $x/*[node-name(.) eq $y]
    

    如果元素名称在命名空间内(注意xs:QName()fn:QName() 之间的区别):

    let $y as xs:string := fn:QName('namespace-uri', 'details1')
    let $x := fn:doc(cts:uri-match('*person.xml'))
    return
       $x/*[node-name(.) eq $y]
    

    【讨论】:

      【解决方案3】:

      另一种方法是使用 xdmp:value() 动态评估 XPath:

      let $y as xs:string := "details1"
      let $x := fn:doc(cts:uri-match('*person.xml'))
      return xdmp:value("$x/" || $y)
      

      如果 $x 是一个大型数据集,则该方法可以通过消除获取集合中每个文档的元素名称的需要来提高性能。

      更多详情,请参见:

      http://docs.marklogic.com/xdmp:value?q=xdmp:value&v=8.0&api=true

      希望对您有所帮助,

      【讨论】:

      • 包含所有关于动态评估、输入清理、错误检测等的常见警告。
      • 同意,Florent,当名称字符串来自未知的外部来源时,这些都是重要的问题。 cts:valid-index-path() 提供了一种验证路径的方法,尽管在某些情况下它可能比所需的更严格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多