In the context of my attempt to implement DITA map resolution in BaseX, I’m experimenting with using the new XQuery update 3 in-memory updates, which seem to be just what I need.
However, my test script fails with:
Stopped at /Users/eliot.kimber/git/mirabel/src/main/xquery/resolve-map-test.xqy, 32/9:
[XUDY0014] Node was not created by transform expression: <mapref.../>.
What subtlety of XQuery update am I missing?
The code works as expected through the start if the THEN clause when $refTarget exists (meaning the mapref was resolved to its target document and we’re trying to construct the new nodes.
The script is:
(: Start of XQuery
😊
import module namespace dutils=http://servicenow.com/xquery/module/now-dita-utils;
import module namespace relpath=http://servicenow.com/xquery/module/now-relpath-utils;
declare %updating function local:resolveMaprefs($context) {
let $maprefs as element()* := $context//mapref[@href][string(@scope) ne 'peer']
let $debug := prof:dump('local:resolveMaprefs(): have ' || count($maprefs) || ' maprefs')
return
for $mapref in $maprefs
let $refTarget as element()? := dutils:resolveReference($mapref/@href)
let $debug := (prof:dump('refTarget:'), prof:dump($refTarget))
return
if (exists($refTarget))
then
let $debug := prof:dump('Got a reference target, attempting to replace original href with it...')
let $newNodes as element() :=
<topicgroup
class="+ map/topicref mapgroup-d/topicgroup "
base="submap {$refTarget/@base} {$mapref/@base}"
xml:base="{relpath:base-uri($refTarget)}"
>{
(: $mapref/@* except ($mapref/@href, $mapref/@format, $mapref/@base),
$refTarget/@* except ($refTarget/@href, $refTarget/@*:DITAArchVersion, $refTarget/@domains, $refTarget/@base) :)
}
<topicmeta class="- map/topicmeta ">
<navtitle class="- topic/navtitle ">{
$refTarget/*[dutils:class(., 'topic/title')]/node()
}</navtitle>
</topicmeta>
{$refTarget/* except ($refTarget/title, $refTarget/topicmeta)}
</topicgroup>
return replace node $mapref with $newNodes
else ()
};
let $mapurl as xs:string := 'bundle-devops-enterprise-dev-ops.ditamap'
let $inputMap as document-node() := db:open('utah', $mapurl)
let $maprefs as element()* := $inputMap//mapref[@href][string(@scope) ne 'peer']
return
(
$maprefs,
$inputMap update {
local:resolveMaprefs(db:open('utah', $mapurl))
}
)
(: End of XQuery :)
A typical input map would be:
<map xml:lang="en-US">
<title>Utah DevOps</title>
<mapref href="now-keys-common.ditamap"/>
<mapref href="devops-change-velocity.ditamap"/>
<mapref href="devops-config.ditamap"/>
</map>
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368