Xquery 表达式求值不起作用

Xquery 表达式求值不起作用,xquery,marklogic,Xquery,Marklogic,我正试图构建一个XML文档,以从函数返回,如下所示。如果我先使用let将其存储在另一个变量中,为什么求值替换会起作用?我能否在适当的位置计算表达式?正如您在最后的结果中所看到的,生成的XML只填充了我在$x变量中存储的变量值 declare function local:oim-to-canonical($oimContent as node()) { let $x := $oimContent/account/domain/text() return <person xm

我正试图构建一个XML文档,以从函数返回,如下所示。如果我先使用
let
将其存储在另一个变量中,为什么求值替换会起作用?我能否在适当的位置计算表达式?正如您在最后的结果中所看到的,生成的XML只填充了我在
$x
变量中存储的变量值

declare function local:oim-to-canonical($oimContent as node()) {
  let $x := $oimContent/account/domain/text()
  return
    <person xmlns="http://schemas.abbvienet.com/people-db/model">
      <account>
        <domain>{ $oimContent/account/domain/text()  }</domain>
        <username>{ $oimContent/account/username/text() }</username>
        <status>{ $oimContent/account/status/text() }</status>
        <x>{ $x }</x>
      </account>
    </person>
};

local:oim-to-canonical(
  <person>
    <account>
      <domain>MYDOMAIN</domain>
      <username>ttt</username>
      <status>ENABLED</status>
    </account>
  </person>
)
将函数local:oim声明为规范($oimContent as node()){
让$x:=$oimContent/account/domain/text()
返回
{$oimContent/account/domain/text()}
{$oimContent/account/username/text()}
{$oimContent/account/status/text()}
{$x}
};
本地:oim至canonical(
MYDOMAIN
ttt
启用
)
结果:

<person xmlns="http://schemas.abbvienet.com/people-db/model">
  <account>
    <domain/>
    <username/>
    <status/>
    <x>MYDOMAIN</x>
  </account>
</person>

MYDOMAIN

这是正确的行为吗?

基于您编写的答案后的注释,您认为在XPath中通配符名称空间将起作用是正确的:

<domain>{ $oimContent/*:account/*:domain/text()  }</domain>
{$oimContent/*:account/*:domain/text()}
然而,这被认为是一个坏的做法时,它是可以避免的。为了执行该XPath,与提供名称空间相比,MarkLogic需要做更多的工作。挑战在于,您的输入XML使用的是空名称空间,而无法指定该名称空间。我将修改输入以使用名称空间:

xquery version "1.0-ml";
declare namespace inp = "input";

declare function local:oim-to-canonical($oimContent as node()) {
  let $x := $oimContent/inp:account/inp:domain/text()
  return
    <person xmlns="http://schemas.abbvienet.com/people-db/model">
      <account>
        <domain>{ $oimContent/inp:account/inp:domain/text()  }</domain>
        <username>{ $oimContent/inp:account/inp:username/text() }</username>
        <status>{ $oimContent/inp:account/inp:status/text() }</status>
        <x>{ $x }</x>
      </account>
    </person>
};

local:oim-to-canonical(
  <person xmlns="input">
    <account>
      <domain>MYDOMAIN</domain>
      <username>ttt</username>
      <status>ENABLED</status>
    </account>
  </person>
)
xquery版本“1.0-ml”;
声明命名空间inp=“input”;
将函数local:oim声明为规范($oimContent as node()){
让$x:=$oimContent/inp:account/inp:domain/text()
返回
{$oimContent/inp:account/inp:domain/text()}
{$oimContent/inp:account/inp:username/text()}
{$oimContent/inp:account/inp:status/text()}
{$x}
};
本地:oim至canonical(
MYDOMAIN
ttt
启用
)

这使得XPath更加明确。在小范围内,差异可能并不重要,但在小范围内,差异累积起来

基于您编写的答案后的注释,您认为在XPath中通配符名称空间将起作用是正确的:

<domain>{ $oimContent/*:account/*:domain/text()  }</domain>
{$oimContent/*:account/*:domain/text()}
然而,这被认为是一个坏的做法时,它是可以避免的。为了执行该XPath,与提供名称空间相比,MarkLogic需要做更多的工作。挑战在于,您的输入XML使用的是空名称空间,而无法指定该名称空间。我将修改输入以使用名称空间:

xquery version "1.0-ml";
declare namespace inp = "input";

declare function local:oim-to-canonical($oimContent as node()) {
  let $x := $oimContent/inp:account/inp:domain/text()
  return
    <person xmlns="http://schemas.abbvienet.com/people-db/model">
      <account>
        <domain>{ $oimContent/inp:account/inp:domain/text()  }</domain>
        <username>{ $oimContent/inp:account/inp:username/text() }</username>
        <status>{ $oimContent/inp:account/inp:status/text() }</status>
        <x>{ $x }</x>
      </account>
    </person>
};

local:oim-to-canonical(
  <person xmlns="input">
    <account>
      <domain>MYDOMAIN</domain>
      <username>ttt</username>
      <status>ENABLED</status>
    </account>
  </person>
)
xquery版本“1.0-ml”;
声明命名空间inp=“input”;
将函数local:oim声明为规范($oimContent as node()){
让$x:=$oimContent/inp:account/inp:domain/text()
返回
{$oimContent/inp:account/inp:domain/text()}
{$oimContent/inp:account/inp:username/text()}
{$oimContent/inp:account/inp:status/text()}
{$x}
};
本地:oim至canonical(
MYDOMAIN
ttt
启用
)

这使得XPath更加明确。在小范围内,差异可能并不重要,但在小范围内,差异累积起来

我同意Dave的观点,使用名称空间作为输入可以让生活更轻松。为了完整性起见,您还可以通过使用元素构造函数而不是默认名称空间使用文字XML来防止此问题:

declare variable $ns := "http://schemas.abbvienet.com/people-db/model";

declare function local:oim-to-canonical($oimContent as node()) {
  let $x := $oimContent/account/domain/text()
  return
    element { fn:QName($ns, "person") } {
      element { fn:QName($ns, "account") } {
        element { fn:QName($ns, "domain") } { $oimContent/account/domain/text()  },
        element { fn:QName($ns, "username") } { $oimContent/account/username/text() },
        element { fn:QName($ns, "status") } { $oimContent/account/status/text() },
        element { fn:QName($ns, "x") } { $x }
      }
    }
};

local:oim-to-canonical(
  <person>
    <account>
      <domain>MYDOMAIN</domain>
      <username>ttt</username>
      <status>ENABLED</status>
    </account>
  </person>
)
声明变量$ns:=”http://schemas.abbvienet.com/people-db/model";
将函数local:oim声明为规范($oimContent as node()){
让$x:=$oimContent/account/domain/text()
返回
元素{fn:QName($ns,“person”)}{
元素{fn:QName($ns,“account”)}{
元素{fn:QName($ns,“domain”)}{$oimContent/account/domain/text()},
元素{fn:QName($ns,“username”)}{$oimContent/account/username/text()},
元素{fn:QName($ns,“status”)}{$oimContent/account/status/text()},
元素{fn:QName($ns,“x”)}{$x}
}
}
};
本地:oim至canonical(
MYDOMAIN
ttt
启用
)
不过,我通常更喜欢文本XML,因为它更密集/更不杂乱


我同意Dave的观点,使用名称空间作为输入可以让生活更轻松。为了完整性起见,您还可以通过使用元素构造函数而不是默认名称空间使用文字XML来防止此问题:

declare variable $ns := "http://schemas.abbvienet.com/people-db/model";

declare function local:oim-to-canonical($oimContent as node()) {
  let $x := $oimContent/account/domain/text()
  return
    element { fn:QName($ns, "person") } {
      element { fn:QName($ns, "account") } {
        element { fn:QName($ns, "domain") } { $oimContent/account/domain/text()  },
        element { fn:QName($ns, "username") } { $oimContent/account/username/text() },
        element { fn:QName($ns, "status") } { $oimContent/account/status/text() },
        element { fn:QName($ns, "x") } { $x }
      }
    }
};

local:oim-to-canonical(
  <person>
    <account>
      <domain>MYDOMAIN</domain>
      <username>ttt</username>
      <status>ENABLED</status>
    </account>
  </person>
)
声明变量$ns:=”http://schemas.abbvienet.com/people-db/model";
将函数local:oim声明为规范($oimContent as node()){
让$x:=$oimContent/account/domain/text()
返回
元素{fn:QName($ns,“person”)}{
元素{fn:QName($ns,“account”)}{
元素{fn:QName($ns,“domain”)}{$oimContent/account/domain/text()},
元素{fn:QName($ns,“username”)}{$oimContent/account/username/text()},
元素{fn:QName($ns,“status”)}{$oimContent/account/status/text()},
元素{fn:QName($ns,“x”)}{$x}
}
}
};
本地:oim至canonical(
MYDOMAIN
ttt
启用
)
不过,我通常更喜欢文本XML,因为它更密集/更不杂乱