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.com

LinkedIn | Twitter | YouTube | Facebook