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

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

servicenow.com

LinkedIn | Twitter | YouTube | Facebook