表达评估不起作用

时间:2016-05-24 19:09:45

标签: xquery marklogic

我正在尝试构建一个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>
)

结果:

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

这是正确的行为吗?

2 个答案:

答案 0 :(得分:4)

在您撰写的答案之后的评论的基础上,您是正确的,通配XPath中的命名空间将起作用:

<domain>{ $oimContent/*:account/*:domain/text()  }</domain>

然而,当它可以避免时,这被认为是一种不好的做法。为了执行该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>
)

这使您的XPath更加明确。规模小,差异可能无关紧要,但规模差异加起来。

答案 1 :(得分:2)

我同意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>
)

我通常更喜欢文字XML,因为它更密集/更简洁..

HTH!