XQuery/Namespace Constructors

Motivation edit

You want to dynamically create namespaces within a document.

Method edit

Use the XQuery namespace constructor. It has the format very similar to the element and attribute constructors:

  namespace {prefix} {uri}

Example edit

declare function local:usage-meta($new-collection as xs:string, $resource as xs:string)
{
    let $schema := doc($new-collection || '/' || $resource)//xs:schema
    let $targetNamespace := $schema/@targetNamespace/string()
    let $metaNamespace := $targetNamespace || '-META'
    let $named := $schema/xs:element/@name/string()
    let $referenced := $schema//xs:element/@ref/string()
    let $top := distinct-values($named[not(.=$referenced)])
    let $newSchema := 
        element xs:schema {
            namespace { "xs" } { "http://www.w3.org/2001/XMLSchema" },
            namespace { "" } { $metaNamespace }, 
            namespace { "usage" } { $targetNamespace },
            namespace { "vc" } { "http://www.w3.org/2007/XMLSchema-versioning" },
            attribute { "targetNamespace" } { $metaNamespace },
            attribute { "elementFormDefault" } { "unqualified" },
            attribute { "attributeFormDefault" } { "unqualified" },
            attribute { "vc:minVersion" } { "1.0" },
            attribute { "vc:maxVersion" } { "1.01" },
            element xs:import {
                attribute { "namespace" } { $targetNamespace },
                attribute { "schemaLocation" } { $resource }
            },
            element xs:element {
                attribute { "name" } { "META" },
                element xs:complexType {
                    element xs:choice {
                        attribute { "minOccurs" } { "0" },
                        attribute { "maxOccurs" } { "unbounded" },
                        for $topElement in $top
                       return 
                            element xs:element {
                                 attribute { "ref" } { "usage:" || $topElement }
                           }
                    }
                }
            }
        }
        (:
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                   xmlns="{$metaNamespace}" 
                   xmlns:usage="{$targetNamespace}" 
                    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
                   targetNamespace="{$metaNamespace}" 
                   elementFormDefault="unqualified" 
                   attributeFormDefault="unqualified"
                    vc:minVersion="1.0" vc:maxVersion="1.01">
    <xs:import namespace="{$targetNamespace}" schemaLocation="{$resource}"/>
    <xs:element name="META">
       <xs:complexType>
           <xs:choice minOccurs="0" maxOccurs="unbounded">
               {for $topElement in $top
                   return <xs:element ref="usage:{$topElement}"/>
               }
               </xs:choice>
           </xs:complexType>
       </xs:element>
    </xs:schema>
    :)
return xmldb:store($new-collection, 'META_' || $resource, $newSchema)
};

Acknowledgement edit

This example was contributed by Loren Cahlandar in Dec. of 2013