Re: [xsl] Fetch a sequence of nodes from input file

Subject: Re: [xsl] Fetch a sequence of nodes from input file
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Wed, 23 Sep 2009 10:24:18 -0700
I this should work for you. Probably a nicer way to do it but does
give you the output you're looking for.

Cheers,

Spencer

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

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

<xsl:template match="*">
<xsl:copy>
	<xsl:copy-of select="@*"/>
	<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<xsl:template match="item[not(ref = '')]" priority="2">
<xsl:variable name="myName" select="ref"/>
<xsl:variable name="myLevel" select="level"/>
<xsl:apply-templates select="preceding-sibling::*[name = $myName][1]"
mode="internal">
	<xsl:with-param name="theLevel" select="$myLevel"/>
</xsl:apply-templates>
</xsl:template>

<xsl:template match="item" mode="internal">
<xsl:param name="theLevel"/>
<xsl:copy>
	<xsl:copy-of select="@*"/>
	<xsl:apply-templates/>
</xsl:copy>
<xsl:variable name="myLevel" select="level"/>
<xsl:apply-templates select="following-sibling::*[1][number(level)
&gt;= $theLevel]">
<xsl:with-param name="theLevel" select="$myLevel"/>
</xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>

On Wed, Sep 23, 2009 at 10:05 AM, rowan@xxxxxxxxxxxxxxxxxxxxx
<rowan@xxxxxxxxxxxxxxxxxxxxx> wrote:
> <xsl:copy-of select="//items/item[name = current()/ref]"/>
>
> This works fine thank you.
>
> Now on to the next problem. Here's a slightly more complicated input file:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <items>
> B  <item>
> B  B  B <name>First</name>
> B  B  B <level>0</level>
> B  B  B <ref/>
> B  B  B <contents>First contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Second</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Second contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Third</name>
> B  B  B <level>2</level>
> B  B  B <ref/>
> B  B  B <contents>Third contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Fourth</name>
> B  B  B <level>3</level>
> B  B  B <ref/>
> B  B  B <contents>Fourth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Fifth</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Fifth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Sixth</name>
> B  B  B <level>2</level>
> B  B  B <ref>Third</ref>
> B  B  B <contents>Sixth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Seventh</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Seventh contents.</contents>
> B  </item>
> </items>
>
> When I find an item with an empty <ref> element, I want to just copy it to
> the putput. But when I find one with a non-empty <ref> element, I want to
> copy <item>s in sequence, starting with the one whose <name> matches the
> <ref> of the source <item> (I'll call this the start item), and finishing
> with the last one whose <level> value is greater than the <level> of the
> start item. So I want to stop just before the <item> whose <level> is <=
> the <level> of the start item.
>
> What I want to produce from the above file is:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <items>
> B  <item>
> B  B  B <name>First</name>
> B  B  B <level>0</level>
> B  B  B <ref/>
> B  B  B <contents>First contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Second</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Second contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Third</name>
> B  B  B <level>2</level>
> B  B  B <ref/>
> B  B  B <contents>Third contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Fourth</name>
> B  B  B <level>3</level>
> B  B  B <ref/>
> B  B  B <contents>Fourth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Fifth</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Fifth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Third</name>
> B  B  B <level>2</level>
> B  B  B <ref/>
> B  B  B <contents>Third contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Fourth</name>
> B  B  B <level>3</level>
> B  B  B <ref/>
> B  B  B <contents>Fourth contents.</contents>
> B  </item>
> B  <item>
> B  B  B <name>Seventh</name>
> B  B  B <level>1</level>
> B  B  B <ref/>
> B  B  B <contents>Seventh contents.</contents>
> B  </item>
> </items>
>
> Any hints on the best way to do this?
>
> I've been trying to do it by finding the position() in the full item
> nodeset of the first and last items in the subset I want to copy (a bit
> like subscripts in an array in a procedural language) but I'm beginning to
> think I'm barking up the wrong tree.
>
> Many thanks - Rowan
>
> --------------------------------------------------------------------
> mail2web - Check your email from the web at
> http://link.mail2web.com/mail2web

Current Thread