RE: [xsl] Problem using Muenchian Method

Subject: RE: [xsl] Problem using Muenchian Method
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Mon, 23 Aug 2004 11:13:00 +0100
Firstly, the variables xpath and cxpath do not hold XPath expressions, they
hold node-sets that result from evaluating those XPath expressions. However,
I don't believe this misunderstanding is the cause of the trouble.

The problem is that key('products-by-id', @id)[1]) selects the first product
in the whole document that has a particular ID, whereas you want the first
one within some subtree of the document. Solving this problem, I'm afraid,
will take me longer than the time I allow myself for writing responses on
this list. Most of the examples of how to do this work with a fixed
hierarchy, it's more difficult with a recursive hierarchy. It becomes musch
easier in XSLT 2.0 with xsl:for-each-group because you can choose any
sequence you like as the grouping population.

Michael Kay

> -----Original Message-----
> From: anarkin@xxxxxxxxxxxx [mailto:anarkin@xxxxxxxxxxxx] 
> Sent: 23 August 2004 10:55
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Problem using Muenchian Method
> 
> Hi,
> 
> I'm having a problem using the 'Muenchian Method' to produce 
> unique output nodes. I'm sure it's not a problem with the 
> method, just my fumbling application of it.
> 
> Here's the XML:
> 
> <?xml version='1.0' encoding='UTF-8'?>
> <?xml-stylesheet href="test.xsl" type="text/xsl"?>
> 
> <categories>
> 	<category name='Duo'>
> 		<product id='W110'/>
> 		<product id='W111'/>
> 		<product id='W112'/>
> 	</category>
> 	<category name='Speciality'>
> 		<category name='Glass'>
> 			<product id='W110'/>
> 			<product id='W111'/>
> 			<product id='W112'/>
> 		</category>
> 		<category name='Wood'>
> 			<category name='Yew'>
> 				<product id='W102'/>
> 				<product id='W115'/>
> 			</category>
> 			<category name='Mahogany'>
> 				<product id='W120'/>
> 				<product id='W115'/>
> 			</category>
> 		</category>
> 	</category>
> </categories>
> 
> Here's the XSLT:
> 
> <?xml version="1.0" encoding="ISO-8859-1"?>
> 
> <xsl:stylesheet	version="1.0" 
> 	xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> 
> 	<xsl:output
> 		method="text"/>
> 	
> 	<xsl:key name="products-by-id" match="@id" use="."/>
> 
> 	<xsl:param name="c"/>
> 	
> 	<xsl:variable name="cxpath" select="
> 		
> /categories//category[@name=$c]//product[generate-id(@id)=gene
> rate-id(key('products-by-id', @id)[1])]
> 		"/>
> 	
> 	<xsl:variable name="xpath" select="
> 		
> /categories/category//product[generate-id(@id)=generate-id(key
> ('products-by-id', @id)[1])]
> 		"/>
> 	
> 	<xsl:variable name="newline">
> 		<xsl:text>
> 		
> </xsl:text>
> 	</xsl:variable>
> 
> 	<xsl:template match="/">
> 	
> 	<xsl:choose>
> 		<xsl:when test="$c">
> 			<xsl:for-each select="$cxpath">
> 				<xsl:value-of 
> select="@id"/><xsl:value-of select="$newline"/>
> 			</xsl:for-each>
> 		</xsl:when>
> 		<xsl:otherwise>
> 			<xsl:for-each select="$xpath">
> 				<xsl:value-of 
> select="@id"/><xsl:value-of select="$newline"/>
> 			</xsl:for-each>
> 		</xsl:otherwise>
> 	</xsl:choose>
> 			
> 	</xsl:template>
> 
> </xsl:stylesheet>
> 
> Here's what I'm trying to do:
> 
> If no $c param is passed to the stylesheet, I want the output 
> to be the @id attribute of every product node (but only once 
> per unique @id). This works fine using the xpath expression 
> held in $xpath.
> 
> If a $c param is passed to the stylesheet (the value of whuch 
> will be identical to the @name attribute of any of the 
> category nodes), I would like the output to be the @id 
> attribute of every product node which is a descendant of the 
> category node which has $c as the value of its @name 
> attribute. But again, I would like the value of each unique 
> @id output only once. The xpath for this is held in $cxpath.
> 
> This works for some nodes but not others. There is no problem 
> if $c=Duo, $c=Wood or $c=Yew. But with other nodes, the 
> output is either nothing at all, or some of the expected @ids 
> are missing. This occurs if they have already appeared in the 
> source xml document, or possibly because they have occured 
> previously in the key.
> 
> Also, I know I have overused the xpath // . This has been 
> mainly to simplify the above example.
> 
> Any help would be greatly appreciated. Thanks.
> 
> Pappa
> 
> -----------------------------------------
> Email provided by http://www.ntlhome.com/

Current Thread