[xsl] XQuery to Report Template Parameters

Subject: [xsl] XQuery to Report Template Parameters
From: Eliot Kimber <ekimber@xxxxxxxxxxxx>
Date: Sun, 17 Feb 2008 09:05:05 -0600
Here's my first stab at an XQuery to usefully report all the template parameters in a single XSLT module and their uses. This just generates a convenient XML result but it could be reworked to generate an HTML page, which might be more useful. I also wrote it to handle a single file because I didn't have time to figure out how/remember to set a directory as an input parameter via OxygenXML, which is where I developed it.

I certainly claim no special XQuery expertise, so I would also welcome any feedback on the coding of the query itself.

Cheers,

Eliot

----- start of query -----
(: Reports template parameters and their uses.

   This query originally developed by W. Eliot Kimber,
   ekimber at reallysi.com. Feel free to adapt, extend
   or distribute as you choose.
:)

declare namespace xsl="http://www.w3.org/1999/XSL/Transform";;


declare function local:getTemplateLabel($template as element()) as xs:string {
concat('Template',
if ($template/@name != '') then concat(' name="',string($template/@name), '"') else '',
if ($template/@match != '') then concat(' match="', string($template/@match), '"') else '')
};


declare function local:echoNodes($nodes as node()*) as node()* {
  for $node in $nodes
      return typeswitch($node)
       case $a as element() return local:echoElement($node)
       default return $node
};

declare function local:echoElement($elem as element()) as element() {

  if (namespace-uri($elem) = "http://www.w3.org/1999/XSL/Transform";)
     then element{name($elem)}{$elem/@*, local:echoNodes($elem/node())}
     else element{name($elem)}{$elem/@*, local:echoNodes($elem/node())}
};

declare function local:reportWithParam($param as element()) as node()* {
<parameter>
<name>{string($param/@name)}</name>
<value>
{if ($param/@select != '')
then string($param/@select)
else $param/node()
}
</value>
<use-context>
{local:getTemplateLabel($param/ancestor::xsl:template[1]), ':&#x0a; ', local:echoElement($param/..)
}</use-context>
</parameter>
};


let $doc := .

let $templateParams := $doc/*/xsl:template/xsl:param
let $apply-templates := $doc/*/xsl:template[descendant::xsl:apply-templates/xsl:with-param]
let $call-templates := $doc/*/xsl:template[descendant::xsl:call-template/xsl:with-param]


return
<param-report xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<parameter-declarations>
{
for $param in $templateParams
order by $param/@name
return <param>
<name>{string($param/@name)}</name>
<datatype>{if (string($param/@as) != '') then string($param/@as) else 'xs:anyType'}</datatype>
<default>{if (string($param/@select) != '') then string($param/@select) else '{None}'}</default>
<tunneling>{if ($param/@tunnel = 'yes') then 'Yes' else 'No'}</tunneling>
<where-declared>
{local:getTemplateLabel($param/..)}
</where-declared>
<matching-uses>
{ if ($param/../@name != '')
then for $call in $call-templates//xsl:call-template[(string(./@name) = string($param/../@name)) and (xsl:with-param[string(@name) = string($param/@name)])]
return <call>{local:getTemplateLabel($call/ancestor::xsl:template[1]), ':&#x0a; ', local:echoElement($call)}</call>
else (),


for $use in $apply-templates[.//xsl:apply-templates/xsl:with-param[string(@name) = string($param/@name)]]
return <apply>{local:getTemplateLabel($use)}</apply>
}
</matching-uses>
</param>
}
</parameter-declarations>
<apply-templates-parameter-uses>
{
for $param in $apply-templates//xsl:apply-templates/xsl:with-param
order by $param/@name
return local:reportWithParam($param)
}
</apply-templates-parameter-uses>
<call-templates-parameter-uses>
{
for $param in $call-templates//xsl:call-templates/xsl:with-param
order by $param/@name
return local:reportWithParam($param)
}
</call-templates-parameter-uses>
</param-report>
---- end of query ----
--
Eliot Kimber
Senior Solutions Architect
"Bringing Strategy, Content, and Technology Together"
Main: 610.631.6770
www.reallysi.com
www.rsuitecms.com


Current Thread