Difference between revisions of "Update name based refs xquery"

(Created page with "For updating name based references to id based based references in a DECOR project or the entire server. Name based references used to be supported because when the editors wh...")
 
Line 1: Line 1:
 
For updating name based references to id based based references in a DECOR project or the entire server. Name based references used to be supported because when the editors when not that sophisticated a lot of hand editing was required. Name based references were a way to make the DECOR files friendlier. However: there is no guarantee that names are unique across projects and it quickly became clear they are ambiguous and have no future.
 
For updating name based references to id based based references in a DECOR project or the entire server. Name based references used to be supported because when the editors when not that sophisticated a lot of hand editing was required. Name based references were a way to make the DECOR files friendlier. However: there is no guarantee that names are unique across projects and it quickly became clear they are ambiguous and have no future.
 +
 +
Note: '''once applied to your project, there is no undo''' unless you keep a copy of the project as backup.
  
 
This xquery will perform the following actions:
 
This xquery will perform the following actions:

Revision as of 06:39, 17 June 2020

For updating name based references to id based based references in a DECOR project or the entire server. Name based references used to be supported because when the editors when not that sophisticated a lot of hand editing was required. Name based references were a way to make the DECOR files friendlier. However: there is no guarantee that names are unique across projects and it quickly became clear they are ambiguous and have no future.

Note: once applied to your project, there is no undo unless you keep a copy of the project as backup.

This xquery will perform the following actions:

  • Lookup name based references to templates and valueSets
  • Lookup the target object and, if only 1 is found update the name based reference to an id based reference
  • If multiple are found, this is included in the final report for you to decide
  • The variable $execute which is false() by default allows you to first assess what the situation is before changing anything

To run the xquery below on the server:

  • Open a webbrowser, surf to: http://<server>:8877
  • Click on ‘dashboard’.
  • Log in as ‘admin’.
  • Open eXide.
  • Click: ‘New XQuery’ (paste the xquery in the box below to the browserscreen)
  • Click: ‘eval’ to run the xquery.
import module namespace get      = "http://art-decor.org/ns/art-decor-settings" at "xmldb:exist:///db/apps/art/modules/art-decor-settings.xqm";
import module namespace art      = "http://art-decor.org/ns/art" at "xmldb:exist:///db/apps/art/modules//art-decor.xqm";
import module namespace vs       = "http://art-decor.org/ns/decor/valueset" at "xmldb:exist:///db/apps/art/api/api-decor-valueset.xqm";
import module namespace templ    = "http://art-decor.org/ns/decor/template" at "xmldb:exist:///db/apps/art/api/api-decor-template.xqm";

(: set to true if you want name based references replaced with oid based references :)
declare variable $execute as xs:boolean  := false();

declare function local:replaceWithOidTemplate($el as element()) {
    let $prefix := $el/ancestor::decor/project/@prefix
    let $ref    := $el/(@contains|@ref|@template|@valueSet)
    let $flex   := if ($el/@flexibility) then $el/@flexibility else 'dynamic'
    let $obj    := templ:getTemplateByRef($ref, $flex, $prefix)/template/template[@id]
    let $upd1   := <current ref="{$ref}" flexibility="{$flex}"/>
    let $upd2   := 
        if (matches($ref,'^[0-9\.]+$') or count($obj) != 1) then (false()) else (
            let $update := if ($execute) then (update insert comment {concat($ref/name(),' name="',$ref,'"')} preceding $ref/parent::*) else ()
            let $update := if ($execute) then (update value $ref with $obj/@id) else ()
            return true()
        )
    (:let $upd3   :=
        if ($el/@flexibility='dynamic') then (
            let $ref := if ($execute) then (update delete $el/@flexibility) else ()
            return true()
        ) else (false()):)
    
    return
        element {name($el)} {
            attribute currentRef {$upd1/@ref},
            attribute currentFlex {$upd1/@flexibility},
            if ($upd2=false()) then () else (attribute newRef {$obj/@id}),
            (:if ($upd3=false()) then () else (attribute newFlex {'dynamic'}),:)
            <text>
            {
                (:if ($upd2=true() and $upd3=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". New value: @', name($ref), '="',$obj/@id,'" and @flexibility="dynamic" has been removed.')
                else :)if ($upd2=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". New value: @', name($ref), '="',string-join(distinct-values($obj/@id),' '),'"')
                (:else if ($upd3=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". Attribute @flexibility="dynamic" has been removed.'):)
                else if (count($obj) > 1) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". However multiple objects were found (',count($obj),', so no change was applied.')
                else (
                    concat(name($el), ' element does not need any change')
                )
            }
            </text>
        }
};

declare function local:replaceWithOidValueSet($el as element()) {
    let $prefix := $el/ancestor::decor/project/@prefix
    let $ref    := $el/(@contains|@ref|@template|@valueSet)
    let $flex   := if ($el/@flexibility) then $el/@flexibility else 'dynamic'
    let $obj    := vs:getValueSetByRef($ref, $flex, $prefix)//valueSet[@id]
    let $upd1   := <current ref="{$ref}" flexibility="{$flex}"/>
    let $upd2   := 
        if (matches($ref,'^[0-9\.]+$') or count($obj) != 1) then (false()) else (
            let $update := if ($execute) then (update insert comment {concat($ref/name(),' name="',$ref,'"')} preceding $ref/parent::*) else ()
            let $update := if ($execute) then (update value $ref with $obj/@id) else ()
            return true()
        )
    (:let $upd3   :=
        if ($el/@flexibility='dynamic' and count($obj) = 1) then (
            let $ref := if ($execute) then (update delete $el/@flexibility) else ()
            return true()
        ) else (false()):)
    
    return
        element {name($el)} {
            attribute currentRef {$upd1/@ref},
            attribute currentFlex {$upd1/@flexibility},
            if ($upd2=false()) then () else (attribute newRef {$obj/@id}),
            (:if ($upd3=false()) then () else (attribute newFlex {'dynamic'}),:)
            <text>
            {
                (:if ($upd2=true() and $upd3=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". New value: @', name($ref), '="',$obj/@id,'" and @flexibility="dynamic" has been removed.')
                else :)if ($upd2=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". New value: @', name($ref), '="',string-join(distinct-values($obj/@id),' '),'"')
                (:else if ($upd3=true()) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". Attribute @flexibility="dynamic" has been removed.'):)
                else if (count($obj) > 1) then
                    concat(name($el), ' element currently has @', name($ref), '="',$ref,'" and @flexibility="',$flex,'". However multiple objects were found (',count($obj),', so no change was applied.')
                else (
                    concat(name($el), ' element does not need any change')
                )
            }
            </text>
        }
};

let $projectPrefix  := ()
let $decors         := 
    if (empty($projectPrefix)) 
    then $get:colDecorData//decor 
    else $get:colDecorData//decor[project/@prefix=$projectPrefix]

return
    <x execute="{$execute}">
    {
        for $ref in ( $decors//*[@valueSet] )
        return
            local:replaceWithOidValueSet($ref)
        ,
        for $ref in ( $decors//transaction/representingTemplate[@ref] | 
                      $decors//relationship[@ref][parent::template][not(ancestor::example)] | 
                      $decors//element[@contains][ancestor::template][not(ancestor::example)] | 
                      $decors//include[@ref][ancestor::template][not(ancestor::example)] 
                    )
        return
            local:replaceWithOidTemplate($ref)
    }
    </x>