MarkLogic 版本:8.0-3.2
看起来,如果在 search:search 选项节点(如 中)中有多个前缀不同但 URI 相同的命名空间声明,则<element xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
除了第一个前缀之外的每个前缀都会在 search:search 调用中丢失。
这是预期的行为吗?它在 ML7.0-4.3 下不存在,并且我不知道在不同前缀下对同一命名空间 uri 的多个声明违反了 XML 命名空间或 xQuery 规范。
非常感谢任何见解。
测试设置脚本:
(:~
: Two transactions:
: (1) Create an element range index on element {myuri:baz}child in "Documents" database
: (2) Insert a test document at /baz/test/test-baz.xml
:
: Expected output: empty sequence
:)
(: Transaction (1): Set up index :)
xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration(),
$dbid := xdmp:database("Documents"),
$rangespec := admin:database-range-element-index("string", "myuri:baz", "child", "http://marklogic.com/collation/", fn:false(), "reject")
return
try {
admin:save-configuration-without-restart(
admin:database-add-range-element-index($config, $dbid, $rangespec)
)
} catch($e) {
"Index already exists? Check logs.",
xdmp:log($e, "debug")
}
;
(: Transaction (2): Insert test document :)
xquery version "1.0-ml";
declare namespace baz = "myuri:baz";
let $uri := "/baz/test/test-baz.xml",
$document :=
<baz:root>
<baz:child>TEST</baz:child>
</baz:root>
return
xdmp:document-insert($uri, $document)
测试脚本(为了清晰/可读性而详细说明):
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
(: additional-query: xmlns:foo first, xmlns:bar second; cts:element: foo:child. Succeeds. :)
declare variable $search-options-1 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>foo:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:foo first, xmlns:bar second; cts:element: bar:child. Fails. :)
declare variable $search-options-2 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>bar:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:bar first, xmlns:foo second; cts:element: bar:child. Succeeds. :)
declare variable $search-options-3 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>bar:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:bar first, xmlns:foo second; cts:element: foo:child. Fails. :)
declare variable $search-options-4 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>foo:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
for $search-options in ($search-options-1, $search-options-2, $search-options-3, $search-options-4)
return
try {
let $test := search:search("", $search-options, 1) instance of element(search:response)
return
if ($test) then "PASS"
else "FAIL" (: won't reach :)
} catch($e) {
$e/error:format-string/fn:string(.)
}
测试输出(注意错误子字符串“No string element range index for child ”---no namespace)
经过
XDMP-ELEMRIDXNOTFOUND: cts:search(fn:collection(), cts:and-query(cts:element-range-query(xs:QName("bar:child"), "=", "TEST", ("collation = http://marklogic.com/collat ion/"), 1), ()), ("score-logtfidf", cts:score-order("descending")), xs:double("1"), ( )) -- 没有子元素的字符串元素范围索引http://marklogic.com/collation /
经过
XDMP-ELEMRIDXNOTFOUND: cts:search(fn:collection(), cts:and-query(cts:element-range-query(xs:QName("foo:child"), "=", "TEST", ("collation = http://marklogic.com/collat ion/"), 1), ()), ("score-logtfidf", cts:score-order("descending")), xs:double("1"), ( )) -- 没有子元素的字符串元素范围索引http://marklogic.com/collation /
更新:当祖先在不同前缀下多次声明相同的命名空间 URI 时,元素级命名空间声明(使用直接构造函数或通过 fn:QName() 序列化)也会在 ML8(不是 ML7)下中断
当任何祖先在不同的前缀下多次声明相同的 URI 时,前缀在 self::* 处丢失:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
(: Serialize namespace w/ fn:QName(), no namespace inheritance: PASS :)
declare variable $search-options-1 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query>
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: Serialize namespace w/ fn:QName(), namespace inheritance, declared once: PASS :)
declare variable $search-options-2 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: Serialize namespace w/ fn:QName(), namespace inheritance, declared twice: FAIL :)
declare variable $search-options-3 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
for $search-options in ($search-options-1, $search-options-2, $search-options-3)
return
try {
let $test := search:search("", $search-options, 1) instance of element(search:response)
return
if ($test) then "PASS"
else "FAIL" (: won't reach :)
} catch($e) {
$e/error:format-string/fn:string(.)
}
输出 ML7.0-4.3:
经过
经过
经过
输出 ML8.0-3.2:
经过
经过
XDMP-ELEMRIDXNOTFOUND: cts:search(fn:collection(), cts:and-query(cts:element-range-query(xs:QName("bar:child"), "=", "TEST", ("collation = http://marklogic.com/collat ion/"), 1), ()), ("score-logtfidf", cts:score-order("descending")), xs:double("1"), ( )) -- 没有子元素的字符串元素范围索引http://marklogic.com/collation /