RE: [xsl] Howto generate a list xpath queries that are used within a template?

Subject: RE: [xsl] Howto generate a list xpath queries that are used within a template?
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Sun, 22 Aug 2004 23:53:34 +0100
> This is a good use case for a schema-aware stylesheet. 
> 
Expanding on my previous reply, the following stylesheet:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
   xsi:schemaLocation="schema-for-xslt20.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
   exclude-result-prefixes="xsi">

<xsl:output method="xml" indent="yes"/>

<xsl:import-schema namespace="http://www.w3.org/1999/XSL/Transform";
     schema-location="schema-for-xslt20.xsd"/>

<xsl:template match="/">
<xsl:if test="not(* instance of schema-element(xsl:transform))">
  <xsl:message terminate="yes">Input document must be a schema-validated
stylesheet</xsl:message>
</xsl:if>
<expressions>
  <xsl:apply-templates/>
</expressions>
</xsl:template>

<xsl:template match="xsl:*" priority="2">
   <!-- match XSLT elements -->
  <xsl:apply-templates select="attribute(*, xsl:expression) except
attribute(*, xsl:pattern)"/>
  <xsl:apply-templates select="attribute(*, xsl:avt)[matches(., '\{[^{]')]"
/>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="*" priority="1">
  <!-- match literal result elements -->
  <xsl:apply-templates select="@* except @xsl:*" />
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="@*">
<expression attribute="{name()}"><xsl:value-of select="."/></expression>
</xsl:template>

<xsl:template match="text()"/>

</xsl:stylesheet>

when run against itself, produces the output:

<?xml version="1.0" encoding="UTF-8"?>
<expressions>
   <expression attribute="test">not(* instance of
schema-element(xsl:transform))</expression>
   <expression attribute="select">child::node()</expression>
   <expression attribute="select">attribute(*, xsl:expression) except
attribute(*, xsl:pattern)</expression>
   <expression attribute="select">attribute(*, xsl:avt)[matches(.,
'\{[^{]')]</expression>
   <expression attribute="select">child::node()</expression>
   <expression attribute="select">@* except @xsl:*</expression>
   <expression attribute="select">child::node()</expression>
   <expression attribute="attribute">{name()}</expression>
   <expression attribute="select">.</expression>
</expressions>

(The "child::node()" entries appear because the schema for XSLT 2.0 expands
the default value of the select attribute of xsl:apply-templates.)

To run this, download Saxon-SA 8.0 from www.saxonica.com (you will need to
apply for an evaluation license) and run it using the command:

java com.saxonica.Transform -val test.xsl test.xsl

You can also, of course, run it against any other stylesheet, provided that
the input stylesheet is validated against the schema for stylesheets. In my
example I added an xsi:schemaLocation attribute to achieve this, but this
could be avoided if you run the transformation from the Java API rather than
from the command line.

Since this is a student exercise, I will leave you to do the job of
explaining how this works.

Michael Kay

Current Thread