我如何动态使用xdmp:value?

问题描述 投票:0回答:1

我正在尝试将xdmp:value与cts:包含在一个函数中,该函数传递给xdmp:value的值是动态的。我对函数式编程非常陌生,因此我的理解可能在这里有很大的缺陷。

这是一个有效的示例,将动态参数放置在cts:contains中,应澄清我的意图:

declare functional local:matchRegion($region as xs:string, $country as xs:string?)
as xs:boolean
{
  let $in-country := '/country[name-variants/variant = $country]/regions/name-variants/variants'
  let $anywhere := '/country/regions/region/name-variants/variant'

  let $found := cts:contains(?, $region)
  return
    if ($country)
      then ($found(xdmp:value($in-country)))
      else ($found(xdmp:value($anywhere)))
};

local:matchRegion("ohio","usa") (: returns true :)

我正在尝试将对xdmp:value的调用预先加载。

这是我尝试过的:1)使用箭头运算符

declare functional local:matchRegion($region as xs:string, $country as xs:string?)
as xs:boolean
{
  let $in-country := '/country[name-variants/variant = $country]/regions/name-variants/variants'
  let $anywhere := '/country/regions/region/name-variants/variant'

  let $found := xdmp:value(?) => cts:contains($region) 
  return
    if ($country)
      then ($found($in-country))
      else ($found($anywhere))
};
local:matchRegion("ohio","usa") (: XDMP-XMLFUNC... Functions cannot be used in the content of an element constructor :)

2)使用简单的地图运算符:

declare functional local:matchRegion($region as xs:string, $country as xs:string?)
as xs:boolean
{
  let $in-country := '/country[name-variants/variant = $country]/regions/name-variants/variants'
  let $anywhere := '/country/regions/region/name-variants/variant'

  let $found := xdmp:value(?) ! cts:contains(?,$region) 
  return
    if ($country)
      then ($found($in-country))
      else ($found($anywhere))
};
local:matchRegion("ohio","usa") (: returns false :)

3)具有匿名功能:

declare functional local:matchRegion($region as xs:string, $country as xs:string?)
as xs:boolean
{
  let $in-country := '/country[name-variants/variant = $country]/regions/name-variants/variants'
  let $anywhere := '/country/regions/region/name-variants/variant'

  let $a := function($x,$y){cts:contains(xdmp:value($x),$y)}
  let $found := $a(?,$region) 
  return
    if ($country)
      then ($found($in-country))
      else ($found($anywhere))
};
local:matchRegion("ohio","usa") (: returns false :)

我具有以与matchRegion类似的意图进行编写的功能,这将涉及更多的条件和更多的xpath表达式;我正在尝试利用动态调用来保持语法可读性和xdmp:value值,以避免对xpath进行不必要的评估。我怎样才能做到这一点?另外,为什么后两个实现返回false?最后,我认为cts:contains对我来说不会做任何特别的事情,因为我需要完全匹配。我对这一切还很陌生,所以请告诉我是否有更好的函数可以调用。

谢谢

更新:这是我要查询的xml文件的示例:

<country>
  <name>Canada</name>
  <name-variants>
    <variant>canada</variant>
  </name-variants>
  <regions>
    <region>
      <name>Manitoba</name>
      <name-variants>
        <variant>manitoba</variant>
        <variant>province of manitoba</variant>
      </name-variants>
    </region>
  </regions>
</country>
xquery marklogic
1个回答
0
投票

你好,FaraBara:

请尝试下面的XQuery函数。

declare function local:matchOrNot( $region as xs:string, 
                                   $country as xs:string)
as xs:boolean
{
  some $i in doc()/country/descendant-or-self::*[contains(., $country)]
  satisfies $i/regions/region/descendant-or-self::*[contains(., $region)]
};

local:matchOrNot("new york", "usa");

您可以测试一些文档,例如:enter image description here

您应该期望获得以下结果:

local:matchOrNot("new york", "usa");  => true
local:matchOrNot("new york", "USA");  => true
local:matchOrNot("New York", "USA");  => true
local:matchOrNot("New York", "usa"); => true
local:matchOrNot("New York", "Canada");  => false
Any combination of "New York" and "Canada" throws back "false"

您的XQuery函数包含多种语法和逻辑错误,因此,它们呈现错误的结果。

© www.soinside.com 2019 - 2024. All rights reserved.