[xsl] Re: Re: Identity transformation (without using xsl:copy)

Subject: [xsl] Re: Re: Identity transformation (without using xsl:copy)
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Sun, 31 Mar 2002 10:20:50 -0800 (PST)
Hi Roger,

Yes, it can be done. In addition to what J.Pietschmann and Dan Sullivan
proposed, the stylesheet bellow will also correctly re-create the
namespace prefixes used in the source xml document.

<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output indent="yes" />
  <xsl:strip-space elements="*" />

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

  <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
  <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

  <xsl:template match="*">
    <xsl:variable name="prefix"
    select="name(namespace::*[. = namespace-uri(current())])" />

    <xsl:variable name="upperName"
    select="translate(local-name(), $lower, $upper )" />

    <xsl:variable name="newName">
      <xsl:choose>
        <xsl:when test="$prefix">
          <xsl:value-of select="concat($prefix, ':', $upperName)" />
        </xsl:when>

        <xsl:otherwise>
          <xsl:value-of select="$upperName" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:element name="{$newName}" namespace="{namespace-uri(.)}">
      <xsl:copy-of select="namespace::*" />
      <xsl:apply-templates select="node()|@*" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>


Hope this helped.

Cheers,
Dimitre Novatchev.

 

"Roger L. Costello" <costello at mitre dot org> wrote:

A few weeks ago I posted a message (below) asking how to do an identity
transformation (without using <xsl:copy>) on instance documents that
contain namespace declarations.  The resounding response was "no way".
[Thanks for your input!]  Okay, after much testing and reading I have
convinced myself that you are correct - <xsl:copy> must be used.  It
seems to me that this puts some serious limits on XSLT.  Consider this
simple problem:  write a stylesheet which does an identity
transformation, but where all element (local) names are converted to
upper case.  For example:

If this is the start document:

<?xml version="1.0"?>
<j:juicers xmlns:j="http://www.juicers.org";;>
     <j:juicer id="omega">
         <name xmlns="http://www.names.org";;>
             Mighty Omega Juicer
         </name>
     </j:juicer>
</j:juicers>

Then this should be the result document:

<?xml version="1.0"?>
<j:JUICERS xmlns:j="http://www.juicers.org";;>
     <j:JUICER id="omega">
         <NAME xmlns="http://www.names.org";;>
             Mighty Omega Juicer
         </NAME>
     </j:JUICER>
</j:JUICERS>

If I could use <xsl:element> then I could easily accomplish this
transformation.  However, it escapes me how to do it if I am forced to
use <xsl:copy>.  

The more general question is: if I use <xsl:copy> to copy over an input
tree to an output tree how can I make modifications to elements names
(such as converting the local part to upper case, as shown above), and
modifications to each element's (non-namespace declaration) attributes?

Thanks!  /Roger




__________________________________________________
Do You Yahoo!?
Yahoo! Greetings - send holiday greetings for Easter, Passover
http://greetings.yahoo.com/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread