我正在尝试构建一个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>
这是正确的行为吗?
答案 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!