表达式评估不起作用
expression evaluation does not work
我正在尝试从下面的函数构建 XML 到 return 的文档。如果我先使用 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>
这是正确的行为吗?
根据您所写答案后的评论,您是对的,在 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 更加明确。小规模,差异可能无关紧要,但在规模上差异会增加。
我同意 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,因为它更 dense/less 混乱..
HTH!
我正在尝试从下面的函数构建 XML 到 return 的文档。如果我先使用 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>
这是正确的行为吗?
根据您所写答案后的评论,您是对的,在 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 更加明确。小规模,差异可能无关紧要,但在规模上差异会增加。
我同意 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,因为它更 dense/less 混乱..
HTH!