[xsl] A non self closed xsl:apply-templates element to create a text node for matching ...

Subject: [xsl] A non self closed xsl:apply-templates element to create a text node for matching ...
From: iwantto keepanon <iwanttokeepanon@xxxxxxxx>
Date: Tue, 5 Dec 2006 06:08:11 +0300 (MSK)
Using XSL 1.0 and xsltproc (Using libxml 20626, libxslt
10117 and libexslt 813).

I have a gallery XML file that I want to transform into
an Atom and a RSS feed.  The XML "setup" file contains
relative URLs.  I need a rule to transform text node and
attribute nodes to absolute URLs.  But coding 2 seperate
templates is kind of dumb.  So I tried to have the
attribute rules (@*) re-use the text (text()) rules.

The only problem is that I have never seen this approach
and I cannot find the syntax in the specs.  I have the
shortest XML and XSL code that represents what I am
doing below.

And my question is, is this "legal".  Note the
"non-self-closed" apply-templates in the
match="@*[...]".  I guess I am creating a text node at
runtime and matching that.  I tried self::text() but, in
attribute context, I dont think that means anything.  Is
there a better way to take attribute text and match it
into another rule?

(sorry if this is obtuse, hopefully the code helps) ...


test.xml:
<?xml version="1.0" encoding="utf-8"?>

<top>
   <img src="../Russia2006/photos/img.jpg"/>
</top>


test.xsl:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml" version="1.0" omit-xml-declaration="no"
   standalone="yes" encoding="utf-8" indent="yes" />

<xsl:template match="/">
   <elem>
      <xsl:apply-templates />
   </elem>
</xsl:template>

<xsl:template match="*">
   <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>

<xsl:template match="text()[ starts-with( ., '../Russia2006/' ) ]">
   <xsl:text>http://site.com/gallery/Russia/2006/</xsl:text>
   <xsl:value-of select="substring-after( ., '../Russia2006/' )" />
</xsl:template>

<xsl:template match="@*">
   <xsl:copy><xsl:value-of select="." /></xsl:copy>
</xsl:template>

<!-- Match relative gallery image URLs only -->
<xsl:template match="@*[
   ( self::src or self::href ) and
   ( '' != substring-before( ., '.jpg' ) or ( '' != substring-before( ., '.gif'
) ) ) ]">

   <xsl:attribute name="{local-name()}">
      <!-- Tried, but does not work ... -->
      <!-- xsl:apply-templates select="." / -->
      <!-- xsl:apply-templates select="text()" / -->
      <!-- xsl:apply-templates select="self::text()" / -->

      <!-- Does work ... creates a runtime text node? -->
      <!-- Cross processor? -->
      <xsl:apply-templates>
         <xsl:value-of select="." />
      </xsl:apply-templates>
   </xsl:attribute>

</xsl:template>

</xsl:stylesheet>


If this is really "leagle" and not just a "feature" of
xlstproc, then great!  If not, help please.

-- 
Rodman

Current Thread