Ramblings of An OverTaxed Mind

I Think I Think.... So Am I?

  Home  |   Contact  |   Syndication    |   Login
  14 Posts | 0 Stories | 16 Comments | 0 Trackbacks

News

Archives

Post Categories

XSLT 2.0 is a wonderful standard.
One of the very useful additions is the ability to control the copying of namespace attribute within the copy and copy-of functions.
However, you don't always have the opportunity to work with the latest and greatest standard.

Below is a set of XSLT templates that will copy an Element in it's entirely without dragging along the namespaces.
Here is an example of how to call the template to copy and element to the destination document.
The example creates an Destination Name call Data the contains all of the contents of the Source node XmlData.

<xsl:element name="Data">
    <!—
COPY CURRENT ELEMENT without Namespaces -->
    <
xsl:call-template name="copy-node" >
        <
xsl:with-param name="node" select="/XmlData" />
    </
xsl:call-template>
</
xsl:element>


<!-- Copy Node: Primary Call -->

<xsl:template name="copy-node" >
<xsl:param name="node" />
<xsl:call-template name="copy-element" >
<xsl:with-param name="element" select="$node" />
</xsl:call-template>
</
xsl:template>
      
<!--
Copy Element
 Reprocesses Element in the output document:
 Copies Attributes
 Copies Text
 Copies Child Nodes
-->
<xsl:template name="copy-element" >
<xsl:param name="element" />
<xsl:if test="$element" >
<xsl:element name="{name($element)}">

<!-- Copy Attributes -->

<xsl:call-template name="copy-attribute" >
<xsl:with-param name="attribute" select="$element/@*" />
</xsl:call-template>
 

<!-- Copy Text -->

<xsl:value-of select="$element/text()"/>
 

<!-- Copy Child Nodes -->

<xsl:for-each select="$element/*" >

<xsl:call-template name="copy-node" >
<xsl:with-param name="node" select="." />
</xsl:call-template>
</xsl:for-each>
              </xsl:element>
</xsl:if>
</xsl:template>
      

<!-- Copy Attribute -->

<xsl:template name="copy-attribute" >
       <xsl:param name="attribute" />
       <xsl:if test="$attribute" >
              <xsl:attribute name="{name($attribute)}">
                     <xsl:value-of select="$attribute" />
              </xsl:attribute>
       </xsl:if>
</xsl:template>
posted on Saturday, July 07, 2007 1:26 PM

Feedback

# re: Copying Elements with No Namespace in XSLT 1.0 10/17/2007 12:25 PM Bembeng Arifin
Hi Douglas,

What a great saver you are, I've been searching on this for the whole day.

Thanks a lot man ;)
PS: I hope you don't mind, I would like to post a link to this article at my blog :)



# re: Copying Elements with No Namespace in XSLT 1.0 12/12/2008 6:43 PM Emerson I. Catalan
Wow you must be doing xslt for a long time. This is the smartest solution I can find in the web for excluding namespaces for xslt 1.0

# re: Copying Elements with No Namespace in XSLT 1.0 5/23/2009 2:27 PM Mathieu Bouchard
This should do the same thing, though you have to write the select such as "/XmlData/*"

<xsl:template name="copy-of">
<xsl:param name="select" />
<xsl:for-each select="$select">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" />
<xsl:value-of select="text()" />
<xsl:call-template name="copy-of">
<xsl:with-param name="select" select="*" />
</xsl:call-template>
</xsl:element>
</xsl:for-each>
</xsl:template>

However, both of these are flawed as they can't handle mixed content. The value of text() is the first fragment only. I am trying to find a way to resolve this but no luck so far

# re: Copying Elements with No Namespace in XSLT 1.0 5/23/2009 3:35 PM Mathieu Bouchard
I figured out how to deal with mixed content. This should do the trick! This version is called similarly to yours, such as "/XmlData"

<xsl:template name="copy-of">
<xsl:param name="select" />
<xsl:for-each select="$select">
<xsl:for-each select="node()|text()">
<xsl:choose>
<xsl:when test="self::*">
<!-- Node -->
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" />
<xsl:call-template name="copy-of">
<xsl:with-param name="select" select="." />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- Text -->
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>



Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: