Trying to apply Query Update 3.0 update/transform operations

Saturday, 3 June 2023 · 1 message
EK
Eliot Kimber3 Jun 2023 19:37 #
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)}"
Quoted text · 1 line
>{
                (: $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<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>

⚡Generated with XQuery