Tutorial :XSLT copy with modifications



Question:

I'm stuck trying to work within these constraints, I'm using XSLT 1.0 {under .net}. I'd like to be able to do the following: i'm xsl:for-each'ing through a set of nodes of type

   <node>       <data> unknown unstructured xml </data>       <owner></owner>     </node>  

i'd like to be able to output

   <node>       <data> unknown unstructured xml </data>       <!--RESULT of calling an XSL template with certain parameters -->     </node>  

from my search so far i thought i could do something like in here:

    <xsl:copy>           <xsl:apply-template name="findownerdetails">             <xsl:with-param name="data" select="something" />          </xsl:apply-template>       </xsl:copy>   

but this is apparently not valid. any suggestions how to get this working or to acheive something similar? I'm afraid i cant just call apply-templates as the template i want will depend on some data i am building up as i for-each through a list of node elements.

Any advice appreciated


Solution:1

<xsl:template match="node">    <node>      <xsl:copy-of select="data"/>      <!-- assuming this next bit in your question example      is something you are happy with -->      <xsl:call-template name="findownerdetails">        <xsl:with-param name="data" select="something" />      </xsl:call-template>     </node>  </xsl:template>  


Solution:2

This is a classic example of a problem that is best solved using and overriding the identity rule :

<xsl:stylesheet version="1.0"      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      <xsl:output omit-xml-declaration="yes" indent="yes"/>      <xsl:strip-space elements="*"/>     <xsl:template match="node()|@*">       <xsl:copy>         <xsl:apply-templates select="node()|@*"/>       </xsl:copy>   </xsl:template>     <xsl:template match="owner">      <owner-details>        <xsl:value-of select="."/>      </owner-details>   </xsl:template>  </xsl:stylesheet>  

When this transformation is applied on this XML document (based on the provided XML document with added attributes and owner details):

<node attr1="x" attr2="y">      <data> unknown unstructured xml </data>      <owner>          <details>              <name>John Smith </name>              <profession>XSLT programmer</profession>          </details>      </owner>  </node>  

The wanted result is produced:

<node attr1="x" attr2="y">     <data> unknown unstructured xml </data>     <owner-details>John Smith XSLT programmer</owner-details>  </node>  

Do note:

  1. The identity template copies every node in the document "as-is" in a recursive fashion.

  2. We only override the identity template for elements that we want to be processed in another way. Any template, whose match pattern is more specific than that of the identity template, overrides it -- the XSLT processor always chooses the most specific matching template for a node.

  3. Using and overriding the identity rule is the most fundamental, the most powerful, the most general and most elegant XSLT design pattern. It is used exclusively in almost all XSLT transformations: for deleting/renaming/modifying/adding specific nodes and keeping all other nodes intact.

  4. The OP has suggested in a comment that this solution doesn't allow parameters to be passed. This is not true. Any template (including the identity rule) can be written to have parameters -- when this is needed. In this particular case it is not necessary to pass parameters via templates.

  5. The template matching owner doesn't need to call another template -- all the owner - specific processing can be done here.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »