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
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> | 
Twitter<https://twitter.com/servicenow> | 
YouTube<https://www.youtube.com/user/servicenowinc> | 
Facebook<https://www.facebook.com/servicenow>

From: Eliot Kimber <eliot.kim...@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
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> | 
Twitter<https://twitter.com/servicenow> | 
YouTube<https://www.youtube.com/user/servicenowinc> | 
Facebook<https://www.facebook.com/servicenow>

Reply via email to