xsl-list
[Top] [All Lists]

RE: Problem using Muenchian Method

2004-08-23 03:13:00
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(_at_)ntlworld(_dot_)com 
[mailto:anarkin(_at_)ntlworld(_dot_)com] 
Sent: 23 August 2004 10:55
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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[(_at_)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/



--+------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--+--





<Prev in Thread] Current Thread [Next in Thread>