Hello!
So as part of an incumbent process, it turns out that the namespaces all
have to be declared on the document element or the downstream processing
fails. That's not correct, but I can't fix the process, so I wrote the
following to make sure all the required namespaces could be declared on
the document element.
<xsl:function name="local:getNamespaces">
<xsl:param name="thisDoc" as="document-node()"/>
<!-- group descendant elements by namespace URI because we don't completely trust the prefix to be unique -->
<xsl:for-each-group select="$thisDoc/descendant-or-self::element()"
group-by="namespace-uri-from-QName(resolve-QName(name(.), .))">
<xsl:variable name="QName" as="xs:QName" select="current-group()[1]/resolve-QName(name(.), .)"/>
<xsl:variable name="prefix" as="xs:string?" select="prefix-from-QName($QName)"/>
<xsl:variable name="namespace" as="xs:anyURI?" select="namespace-uri-from-QName($QName)"/>
<!-- don't create a namespace for the default namespace; only if there's a defined prefix (empty string = false) -->
<xsl:if test="$prefix">
<xsl:namespace name="{$prefix}" select="$namespace"/>
</xsl:if>
</xsl:for-each-group>
</xsl:function>
It works, but I find myself wondering how I could declare the return
type of the function.
as="namespace()" does not work; namespace() isn't a node test.
I realize this is a weird case that's a workaround for a bug elsewhere
in the process, but wanting to be able to extract and manipulate a
sequence of namespaces seems like a reasonable thing for a function to
do.
What am I missing?
--
Graydon Saunders | graydonish@xxxxxxxxx
^fs oferiode, pisses swa mfg.
-- Deor ("That passed, so may this.")
|