Here’s my working function, which applies itself recursively, resulting in a completely resolved map.
The only thing I had to do to my existing supporting code was update it to take a base URI parameter to account for the loss of base URIs in the process of resolving references and copying nodes during the
update.
I had not actually realized there was an XQuery Update 3.0 spec, so this was very instructive.
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, $baseUri as xs:string?) {
let $baseUri as xs:string := if (exists($baseUri)) then $baseUri else relpath:base-uri($context)
let $maprefs as element()* := $context//mapref[@href][string(@scope) ne 'peer']
return
for $mapref in $maprefs
let $targetUri as xs:string := relpath:resolve-uri(string($mapref/@href), $baseUri)
let $refTarget as element()? := dutils:resolveReference($mapref/@href, $baseUri)
let $newTarget as element()? :=
if (exists($refTarget//mapref[@href][string(@scope) ne 'peer']))
then $refTarget transform with { local:resolveMaprefs(., $targetUri) }
else $refTarget
return
if (exists($newTarget))
then
let $newAtts as attribute()* :=
($mapref/@* except ($mapref/@href, $mapref/@format, $mapref/@base),
$newTarget/@* except ($newTarget/@href, $refTarget/@*:DITAArchVersion, $newTarget/@domains, $newTarget/@base)
)
let $newAtts as attribute()* :=
for $att in $newAtts
let $attname as xs:string := name($att)
group by $attname
return $att[1]
let $newNodes as element() :=
<topicgroup
class="+ map/topicref mapgroup-d/topicgroup "
base="submap {$refTarget/@base} {$mapref/@base}"
xml:base="{relpath:base-uri($refTarget)}"
>{$newAtts}
<topicmeta class="- map/topicmeta ">
<navtitle class="- topic/navtitle ">{
$newTarget/*[dutils:class(., 'topic/title')]/node()
}</navtitle>
</topicmeta>
{$newTarget/* except ($newTarget/title, $newTarget/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)
return
(
$inputMap transform with { local:resolveMaprefs(., relpath:base-uri(.)) }
,()
)
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
LinkedIn | Twitter | YouTube | Facebook
From:
Eliot Kimber <eliot.kimber@servicenow.com>
Date: Saturday, June 3, 2023 at 2:00 PM
To: basex-talk@mailman.uni-konstanz.de <basex-talk@mailman.uni-konstanz.de>
Subject: [basex-talk] Trying to apply Query Update 3.0 update/transform operations
I found my error: I was passing in a variable from outside the transform/update call, rather than using the context node.
This is the correct invocation:
return
(
$inputMap transform with { local:resolveMaprefs(.) }
,()
)
I also successfully applied the transform recursively, so I think I have, despite my best efforts, figured out how do this map resolution as efficiently as possible.
Cheers,
E.
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368