Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
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 tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old September 23rd, 2010, 10:11 AM
Authorized User
 
Join Date: Jan 2010
Posts: 12
Thanks: 2
Thanked 0 Times in 0 Posts
Default How to copy all elements within the path to the root

Hello,

I am looking for some hours for a solution for a very simple problem:
Copy all leaves from a tree with all elements on the way to the root.

I tried:

java -jar saxon9he.jar -s:in.xml -xsl:test.xsl -o:out.xml

in.xml

Code:
<nodes>
	<node id="a1">
		<node id="b1">
			<node id="c1"/>
			<node id="c2"/>
		</node>
	</node>
	<node id="a2"/>
</nodes>
test.xsl

Code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- copy elements without children including all the elements within the path to the root (i.e. full path)  -->
<xsl:template match="/">
	<nodes>
		<xsl:apply-templates />
	</nodes>
</xsl:template>

<xsl:template match="node[not(descendant::node)]"> 
	<xsl:for-each select="ancestor-or-self::*[count(ancestor::*)>0]"> 
		<node id="{@id}" />
	</xsl:for-each> 
</xsl:template> 
 
</xsl:stylesheet>
out.xml should be a simple copy of the "full path" to the elements, that do not have any children

Code:
<nodes>
	<node id="a1">
		<node id="b1">
			<node id="c1"/>
		</node>
	</node>
	<node id="a1">
		<node id="b1">
			<node id="c2"/>
		</node>
	</node>
	<node id="a2"/>
</nodes>

with the given stylesheet the xml transforms to a list (not surprisingly).

Code:
<nodes>
<node id="a1"/><node id="b1"/><node id="c1"/>
<node id="a1"/><node id="b1"/><node id="c2"/>
<node id="a2"/>
</nodes>
Any hints how to copy all ancestors of a given node?

Best regards

Chrsitian
Reply With Quote
  #2 (permalink)  
Old September 23rd, 2010, 10:30 AM
Friend of Wrox
Points: 6,673, Level: 34
Points: 6,673, Level: 34 Points: 6,673, Level: 34 Points: 6,673, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,242
Thanks: 0
Thanked 244 Times in 243 Posts
Default

Interesting problem, here is an XSLT 2.0 stylesheet that does the job with Saxon 9, at least for the sampleinput you posted:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="descendant::*[not(node())]"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="*[not(descendant::node())]">
    <xsl:variable name="ancestors" select="ancestor-or-self::*[position() lt last()]"/>
    <xsl:apply-templates select="$ancestors[1]" mode="tree">
      <xsl:with-param name="ancestors" select="$ancestors"/>
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="*" mode="tree">
    <xsl:param name="ancestors"/>
    <xsl:if test="$ancestors intersect .">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates mode="tree">
          <xsl:with-param name="ancestors" select="$ancestors"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
  #3 (permalink)  
Old September 23rd, 2010, 10:41 AM
Authorized User
 
Join Date: Jan 2010
Posts: 12
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Thank you very much. The code is running fine.

The problem looked quite simple to me - the solution quite complicated. Normaly XSLT is exactly the other way. Is this a problem I should better solve within the relational database?

Best regards

Christian
Reply With Quote
  #4 (permalink)  
Old September 23rd, 2010, 11:41 AM
Friend of Wrox
Points: 6,673, Level: 34
Points: 6,673, Level: 34 Points: 6,673, Level: 34 Points: 6,673, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,242
Thanks: 0
Thanked 244 Times in 243 Posts
Default

Three templates is a complicated solution? The first template creates the root element of the result tree and select the nodes you are interested in (i.e. those without child nodes) for further processing, then for each of the selected nodes the second template finds the elements forming a subtree you want to copy and the third template does the copying.

As for solving the problem "within the relational database", I don't know how the XML input relates to any relational data so I can't tell anything about that.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to copy elements to new file geek.shrek XSLT 6 January 10th, 2010 08:35 AM
copy-of select= not returning all elements jay_c XSLT 8 August 8th, 2009 01:38 PM
path for nested elements rjonk XSLT 7 November 20th, 2006 05:43 AM
changing root path in file manager codergirl BOOK: ASP.NET Website Programming Problem-Design-Solution 3 November 11th, 2004 04:21 PM
Fixing virtual directory root path issue seanmayhew BOOK: ASP.NET Website Programming Problem-Design-Solution 1 November 10th, 2004 10:45 PM



All times are GMT -4. The time now is 02:20 PM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.