Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 2nd, 2010, 07:50 AM
Authorized User
 
Join Date: Oct 2010
Posts: 25
Thanks: 8
Thanked 0 Times in 0 Posts
Default Recursive templates

Hello,
I have this xml file which in it has a recursive inner node:
Code:
<part_structure>
       
        <assembly>
            <part>
            	<part ref="PART1"/>
            </part>
            <id>PART1</id>
            <find>0010C</find> 
            <quantity>0</quantity> 
            <usage>X</usage> 
            <level>0</level>
             
             
<childs>
             
            <partnode>
            	    <part>
            	    	<part ref="PART2"/>
            	    </part>
            	      <id>PART2</id>
            	     <find>56900</find>
            	     <quantity>1</quantity>
            	     <usage>Standard</usage> 
            	     <level>1</level>
            </partnode> 
  
            
            <partnode>
            	     <part>
	            	     <part ref="PART3"/>
            	     </part>
            	      <id>PART3</id>
            	     <find>69T1A</find>
            	     <quantity>1</quantity>
            	     <usage>Standard</usage> 
            	     <level>1</level>
            </partnode> 
          
        <assembly>
           
            <part>
			  <part ref="PART4"/>
            </part>
            <id>PART4 </id>
            <find>00105</find> 
            <quantity>1</quantity> 
            <usage>Standard</usage> 
            <level>1</level>        
            <childs>
             <partnode>
            	     <part>
					    <part ref="PART5"/>
                     </part>	
            	     <id>PART5</id>
            	     <find>6221A</find>
            	     <quantity>1</quantity>
            	     <usage>Standard</usage> 
            	     <level>2</level>
             </partnode> 
            </childs>	
        </assembly>
     </childs>
   </assembly>

 </part_structure>
as can be seen the childs node can have partnode and assembly, the assembly can then have a recursive structure. So in theory the assembly in the child node can be something like
Code:
       <assembly>
           
            <part>
			  <part ref="PART4"/>
            </part>
            <id>PART4 </id>
            <find>00105</find> 
            <quantity>1</quantity> 
            <usage>Standard</usage> 
            <level>1</level>        
            <childs>
             <partnode>
            	     <part>
					    <part ref="PART5"/>
                     </part>	
            	     <id>PART5</id>
            	     <find>6221A</find>
            	     <quantity>1</quantity>
            	     <usage>Standard</usage> 
            	     <level>2</level>
             </partnode> 
			      <assembly>
           
            <part>
			  <part ref="PART41"/>
            </part>
            <id>PART4 </id>
            <find>00105</find> 
            <quantity>1</quantity> 
            <usage>Standard</usage> 
            <level>1</level>        
            <childs>
             <partnode>
            	     <part>
					    <part ref="PART51"/>
                     </part>	
            	     <id>PART5</id>
            	     <find>6221A</find>
            	     <quantity>1</quantity>
            	     <usage>Standard</usage> 
            	     <level>2</level>
             </partnode> 
			 <assembly>
			 ....
			 </assembly>
            </childs>	
        </assembly>
     </childs>
   </assembly>

I have written this code:
Code:
<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="2.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:fn="http://www.w3.org/2005/xpath-functions"
	xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
	xmlns:err="http://www.w3.org/2005/xqt-errors"
	xmlns:exp="urn:oid:1.0.10303.28.2.1.1"
	xmlns:doc="urn:oid:1.0.10303.28.2.1.3"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                   
              exclude-result-prefixes="exp doc xsi xs xdt err fn">

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

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


  
  <xsl:template match="part_structure">
    <xsl:element name="part-structure">
        <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="part_structure/assembly">
     <xsl:element name="assembly">
       <xsl:attribute name="id">
	 <xsl:value-of select="part/part/@ref"/>
       </xsl:attribute>
       <xsl:attribute name="find">
                 <xsl:value-of select="find"/>
       </xsl:attribute>
       <xsl:attribute name="quantity">
                <xsl:value-of select="quantity"/>
       </xsl:attribute>
       <xsl:attribute name="usage">
                <xsl:value-of select="usage"/>
       </xsl:attribute>
       <xsl:attribute name="level">
                <xsl:value-of select="level"/>
       </xsl:attribute>
          <xsl:apply-templates/> 
     </xsl:element>
  </xsl:template>
  <!--  these five templates disallow the contents of the given nodes to be printed -->
  <xsl:template match="part_structure/assembly/id"/>
  <xsl:template match="part_structure/assembly/find"/>
  <xsl:template match="part_structure/assembly/quantity"/>
  <xsl:template match="part_structure/assembly/usage"/>
  <xsl:template match="part_structure/assembly/level"/>
  
    <xsl:template  match="childs">
           <xsl:for-each select="partnode">
                <xsl:element name="part">
	        <xsl:attribute name="id">
	             <xsl:value-of select="part/part/@ref"/>
	        </xsl:attribute>
	         <xsl:attribute name="find">
	                 <xsl:value-of select="find"/>
	       </xsl:attribute>
	       <xsl:attribute name="quantity">
	                <xsl:value-of select="quantity"/>
	       </xsl:attribute>
	       <xsl:attribute name="usage">
	                <xsl:value-of select="usage"/>
	       </xsl:attribute>
	       <xsl:attribute name="level">
	                <xsl:value-of select="level"/>
	       </xsl:attribute>
                </xsl:element>
           </xsl:for-each>
           <xsl:apply-templates/>
    </xsl:template>
    
     <xsl:template match="childs/assembly">
    
     <xsl:element name="assembly">
       <xsl:attribute name="id">
	 <xsl:value-of select="part/part/@ref"/>
       </xsl:attribute>
       <xsl:attribute name="find">
                 <xsl:value-of select="find"/>
       </xsl:attribute>
       <xsl:attribute name="quantity">
                <xsl:value-of select="quantity"/>
       </xsl:attribute>
       <xsl:attribute name="usage">
                <xsl:value-of select="usage"/>
       </xsl:attribute>
       <xsl:attribute name="level">
                <xsl:value-of select="level"/>
       </xsl:attribute>
          <xsl:apply-templates/> 
     </xsl:element>
  </xsl:template>
  
  <!--<xsl:template match="part_structure/assembly/childs/assembly/id"/>
  <xsl:template match="part_structure/assembly/childs/assembly/find"/>
  <xsl:template match="part_structure/assembly/childs/assembly/quantity"/>
  <xsl:template match="part_structure/assembly/childs/assembly/usage"/>
  <xsl:template match="part_structure/assembly/childs/assembly/level"/>
  
   <xsl:template match="part_structure/assembly/childs/assembly/id"/>
  <xsl:template match="part_structure/assembly/childs/assembly/find"/>
  <xsl:template match="part_structure/assembly/childs/assembly/quantity"/>
  <xsl:template match="part_structure/assembly/childs/assembly/usage"/>
  <xsl:template match="part_structure/assembly/childs/assembly/level"/>  -->
  
</xsl:stylesheet>
this gives me the following result:
Code:

   <part-structure>
       
        <assembly id="PART1" find="0010C" quantity="0" usage="X" level="0">
            
            	
            
            
             
             
             
            
             
             
         <part id="PART2" find="56900" quantity="1" usage="Standard" level="1"/>
         <part id="PART3" find="69T1A" quantity="1" usage="Standard" level="1"/>
             
            
            	    
            	    	
            	    
            	      PART2
            	     56900
            	     1
            	     Standard 
            	     1
             
  
            
            
            	     
	            	     
            	     
            	      PART3
            	     69T1A
            	     1
            	     Standard 
            	     1
             
          
        <assembly id="PART4" find="00105" quantity="1" usage="Standard" level="1">
           
            
			  
            
            PART4 
            00105 
            1 
            Standard 
            1        
            <part id="PART5" find="6221A" quantity="1" usage="Standard" level="2"/>
             
            	     
					    
                     	
            	     PART5
            	     6221A
            	     1
            	     Standard 
            	     2
              
            	
        </assembly>
     
      </assembly>

   </part-structure>
The result is correct and it also works when there is inner assembly nodes, the problem is with the output of the values of the nodes. first I tried to get rid of there by writing empty templates, at the end of the xslt code, but I realised that if there are recursive inner assembly nodes this won't help at all.

So my question is how can I get rid of these node values?

cheers,
ehsan
 
Old November 2nd, 2010, 08:09 AM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

It appears you are making life a little bit complicated for yourself.

The short answer is to change the <xsl:apply-templates/> line so that you are only applying the template to the children you want to - e.g. <xsl:apply-templates select="childs"/>.

A longer answer would be to shorten your entire XSLT down to three simple templates, like below - reducing both redundancy, complexity and readability.

Code:
  <xsl:template match="part_structure">
      <part-structure>
        <xsl:apply-templates/>
      </part-structure>
  </xsl:template>
  
  <xsl:template match="assembly">
      <assembly id="{part/part/@ref}" find="{find}" quantity="{quantity}" usage="{usage}"
                level="{level}">
         <xsl:apply-templates select="childs"/>
      </assembly>
  </xsl:template>
  
    <xsl:template match="childs">
           <xsl:for-each select="partnode">
         <part id="{part/part/@ref}" find="{find}" quantity="{quantity}" usage="{usage}"
               level="{level}"/>
               </xsl:for-each>
           <xsl:apply-templates select="assembly"/>
    </xsl:template>
__________________
/- Sam Judson : Wrox Technical Editor -/

Think before you post: What have you tried?
The Following User Says Thank You to samjudson For This Useful Post:
ehsansad (November 2nd, 2010)
 
Old November 2nd, 2010, 08:28 AM
Authorized User
 
Join Date: Oct 2010
Posts: 25
Thanks: 8
Thanked 0 Times in 0 Posts
Default

Thanks again,
saved me twice in a day :-) much appreciated.





Similar Threads
Thread Thread Starter Forum Replies Last Post
Exit from recursive apply-templates scubin XSLT 4 May 1st, 2010 07:46 PM
Recursive Coding arnabghosh Classic ASP Professional 2 July 9th, 2007 02:06 AM
Recursive template - Please Help! Tre XSLT 5 March 20th, 2007 11:23 AM
recursive query cathiec SQL Language 2 August 25th, 2006 05:58 AM
Recursive Function MargateFan XSLT 2 May 4th, 2006 02:52 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.