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 servicenow.comhttps://www.servicenow.com LinkedInhttps://www.linkedin.com/company/servicenow | Twitterhttps://twitter.com/servicenow | YouTubehttps://www.youtube.com/user/servicenowinc | Facebookhttps://www.facebook.com/servicenow
basex-talk@mailman.uni-konstanz.de