【问题标题】:Rewrite MarkLogic xml document dynamically based on strings in XQuery基于 XQuery 中的字符串动态重写 MarkLogic xml 文档
【发布时间】:2016-11-27 18:37:48
【问题描述】:

我需要一个能够重写文档的 XQuery 函数,特别是返回子节点的子集,基于指定要检索的节点名称的字符串数组。如果应该满足如下定义,并且需要使用任意文档。

local:apply-node-includes($document, $includedNodeNames as xs:string*)

鉴于我有一些 xml 文档

let $doc := 
  <foo a="b">
    <bar>hello</bar>
    <baz>1</baz>
    <bang>
      <text>world</text>
    </bang>
  </foo>')

然后该函数应该转换文档,以便只返回名称在 $includedNodes 中指定的子节点。

示例local:apply-node-includes($doc, 'baz') 将返回

<foo a="b">
  <baz>1</baz>
</foo>

示例local:apply-node-includes($doc, ('bar','bang'))) 将返回

<foo a="b">
  <bar>hello</bar>
  <bang>
    <text>world</text>
  </bang>
</foo>

我尝试在节点上进行迭代,和/或使用某种形式的递归类型开关,但到目前为止还无法做到正确。如果它完全递归地工作,那就太酷了,所以 'bang.text' 将只包括孙文本节点而不包括它们的任何兄弟姐妹,但也许这要求太多了!

【问题讨论】:

  • 考虑让您的函数采用一系列 xs:QNames 而不是字符串。您所拥有的工作是因为您的 XML 使用默认命名空间,但是在存在命名空间的情况下,您会遇到问题。

标签: xml xquery marklogic


【解决方案1】:

我不确定这是否是最优雅的解决方案,但似乎满足您的要求。此处的函数重新创建所传递文档的根元素,然后包含其元素名称与传递列表中的任何字符串匹配的任何直接子元素(及其所有属性和子元素)。

declare function local:apply-node-includes( $doc as item(), $includedNodeNames as xs:string*) as item()
{
   (: Recreate the root element :)
   element {name($doc)} 
   { (: Replicate root element's attributes :)
     (for    $attribute in $doc/@* return $attribute),
     (: Replicate root element's immediate children having any of given names :)
     (for    $element in $doc/* where name($element) = $includedNodeNames 
      return $element)
   }
};

let $doc := 
  <foo a="b">
    <bar>hello</bar>
    <baz>1</baz>
    <bang>
      <text>world</text>
    </bang>
  </foo>
return local:apply-node-includes($doc, ('bar','bang'))

输出:

<foo a="b"><bar>hello</bar><bang><text>world</text></bang></foo>

【讨论】:

  • 我已经更正了这些错别字,感谢您的回答。我接受了你的,但发布了一个精致的版本供其他人效仿。
【解决方案2】:

@DavidDeneberg 给出了一个很好的答案,但我设法使用一些 xpath 进一步简化它,以便为其他人发布。

declare function local:apply-node-includes($doc as element(), $includedNodeNames as xs:string*) as element()?
{
  element {node-name($doc) }
  {
    $doc/@*,
    $doc/*[name(.)=$include-names]
  }
};

这本书在这个主题上也非常有用 https://en.wikibooks.org/wiki/XQuery/Filtering_Nodes 并演示了您需要能够处理问题的孙子部分的递归身份转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 2018-10-01
    相关资源
    最近更新 更多