[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Select Deepest Node only in Iteration


Subject: Re: [xsl] Select Deepest Node only in Iteration
From: "J. Zhang" <j.zhang@xxxxxx>
Date: Fri, 13 Jul 2007 13:31:04 +0200

Michael,

A problem, reversing (descending) works, but selecting the top of the
list does not work with position(). I have been testing by outputting
some numbers from the following 2 functions.


<a><xsl:value-of select="count(ancestor::node())"/></a>

<b><xsl:value-of select="position()"/></b>

This the output I am getting for the first item in the list:

<a>5</a>

<b>74</b>

So the position() function does not work in my case. That is why I think
I need to match in an if statement with count(ancestor::node()), e.g.

<xsl:if test="count(ancestor::node())=5">

Then I am getting the top of the list, a problem is however that I am
reading multiple documents and match with multiple keywords. So I cannot
set it adhoc this way.

Could you help me? This is my stylesheet, I hope it is readable. I am
loading 2 files (myfiles.xml, mykeywords.xml) in my stylesheet, which
each consist of a list of files and words respectively.

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="saxon"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f">

<xsl:output method="xml" encoding="iso-8859-1" indent="no"/>

<xsl:template match="/">

<xsl:for-each select="document('myfiles.xml')//element">
	
<xsl:variable name="filename" select="."/>

<xsl:for-each select="document('mykeywords.xml')//element">

<xsl:variable name="term" select="."/>

<xsl:for-each select="document($filename)">
					
<xsl:for-each select="//*">

<xsl:sort select="count(ancestor::node())" order="descending"/>


<xsl:if test="matches(string(self::node()), concat('\W', $term, '\W'),
'im')">

<a><xsl:value-of select="count(ancestor::node())"/></a>
<b><xsl:value-of select="position()"/></b>
<c><xsl:number /></c>

<xsl:variable name="content" select="string(self::node())" />

<xsl:text>
</xsl:text>						

<topic><xsl:value-of select="$term"/></topic>

<xsl:variable name="before"
select="string-length(substring-before($content, $term))" />

<xsl:variable name="after"
select="string-length(substring-after($content, $term))" />

<path>/<xsl:value-of select="concat(saxon:path(), ' ', '0', ' ',
$after)"/></path>

<content><xsl:value-of select="$content"/></content>

<xsl:text>
</xsl:text>

</xsl:if>


</xsl:for-each>

</xsl:for-each>

</xsl:for-each>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>


Why won't it work in my case, and is there a solution?



Michael Kay wrote:
> The simplest change to your code is to add an xsl:sort to your for-each that
> sorts the matching nodes by descending depth. That's <xsl:sort
> select="count(ancestor::node)" order="descending"/>. Then you can return a
> value only when position()=1. 
> 
> Michael Kay
> http://www.saxonica.com/
> 
>> -----Original Message-----
>> From: J. Zhang [mailto:j.zhang@xxxxxx] 
>> Sent: 12 July 2007 15:47
>> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>> Subject: [xsl] Select Deepest Node only in Iteration
>>
>> I have already checked the XSL FAQ at 
>> http://www.dpawson.co.uk/ and explored the history of this 
>> mailinglist. I could not find the answer, that is why I am 
>> posting here.
>>
>> I am matching the content of XML elements this way in a 
>> for-each iteration:
>>
>> xsl:if test="matches(string(self::node()), concat('\W', 
>> $term, '\W'), 'im')">
>>
>> I return the absolute path where $term occurs in the 
>> transformation. The result after the transformation is for 
>> example this for Word 1:
>>
>> //article
>>
>> //article/body[1]
>>
>> //article/body[1]/section[6]
>>
>> //article/body[1]/section[6]/normallist[6]
>> 							
>> //article/body[1]/section[6]/normallist[6]/item[1]
>>
>> The problem is that I only want the longest path, e.g. the 
>> deepest node of this leave. I need to set a condition that 
>> only returns something when the for-each iteration has come 
>> to the longest path of this leave, but I could not find a way 
>> to do this.
>>
>> Any help would be greatly appreciated! Thanks!


Current Thread
Keywords