RE: transforming unique nodes thru XSLT

Subject: RE: transforming unique nodes thru XSLT
From: Bill Martschenko <billmartschenko@xxxxxxxxx>
Date: Tue, 28 Sep 1999 23:38:46 -0700 (PDT)
Here is an IE5 solution using xsl:script.  Michael's
solution below uses notation not yet supported in IE. 
The solution here is very similar to one for the post
"Grouping and Unique Lists".

The basic idea is to list all "b" nodes in sorted
order where key = @item.  Marching thru the sorted
list, we only output the first one in each sorted
group.

Attached is the XSL.

Bill

<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/TR/WD-xsl";>

<xsl:template match="/">
<html>
    <body bgcolor="#EEE8AA">
        <h2>Items, unsorted, duplicates allowed:</h2>
        <table border="1">
           
<thead><th>Item</th><th>uniqueID()</th></thead>
            <xsl:for-each select="//b">
                <tr>
                    <td><xsl:value-of
select="@item"/></td>
                    <td
align="center"><xsl:eval>uniqueID(this)</xsl:eval></td>
                </tr>
        </xsl:for-each>
        </table>

        <h2>Items, sorted, duplicates removed:</h2>
        <table border="1">
           
<thead><th>Item</th><th>uniqueID()</th></thead>
            <!-- IsItemStart(this) returns whether the
context node. an item       -->
            <!-- attribute, is also the first item of
its kind, in document order. -->
            <!-- This test is valid here for grouping
because the "ordered-by"     -->
            <!-- predicate above must do a "stable
sort".  Here, stable sort       -->
            <!-- means preserve document order for
sorting keys that match.        -->
            <xsl:for-each select="//b"
order-by="@item">
                <xsl:if expr="IsItemStart(this)">
                    <tr>
                        <td><xsl:value-of
select="@item"/></td>
                        <td
align="center"><xsl:eval>uniqueID(this)</xsl:eval></td>
                    </tr>
                </xsl:if>
            </xsl:for-each>
        </table>
    </body>
</html>
</xsl:template>

<xsl:script>
    function FirstItem(bNode)
    {
        // define pattern for selecting first node in
the same item group, in document order
        // example:  (//b)[@item='pencil'][0]
        itemNode = bNode.selectSingleNode("@item");
        pattern = "(//b)[@item='" + itemNode.text +
"'][0]";
        return itemNode.selectSingleNode(pattern);
    }
    function IsItemStart(bNode)
    {
        return uniqueID(FirstItem(bNode)) ==
uniqueID(bNode);
    }
</xsl:script>

</xsl:stylesheet>




> 
> RE: transforming unique nodes thru XSLT
> From: Kay Michael <Michael.Kay@xxxxxxx>
> Date: Fri, 24 Sep 1999 10:00:54 +0100
> 
> You can do something like:
>  
> for-each select="//b"
>   variable name="item" select="@item"/
>   variable name="remainder"
select="following::item[@item=$item]"/
>   if test="not($remainder)"
>      ... do the output ...
>   /if
> /for-each
>   
> 
> -----Original Message-----
> From: Anand K [mailto:anandk@xxxxxxxxx]
> Sent: 24 September 1999 03:38
> To: xsl-list@xxxxxxxxxxxxxxxx
> Subject: transforming unique nodes thru XSLT
> 
> 
> Hello everyone, 
> 
> I have an XSL Transformation question. I hope I can
raise XSLT issues here.
> I am new to XSL and want to write a template 
> to transform only unique nodes from a well formed
XML document to HTML. 
> 
> 
> Below is a small snippet of this well formed
document which I want to
> transform 
> <xyz> 
>     ... 
>     ... 
>     <a name="school"> 
>         <a name="grade5"> 
>             <b item="pencil"/> 
>             <b item="paper"/> 
>         </a> 
>         <a name="grade10"> 
>             <b item="pen"/> 
>             <b item="paper"/> 
>             <b item="backpack"/> 
>         </a> 
>     </a> 
>     <a name="office"> 
>         <b item="cuibicle"/> 
>         <b item="paper"/> 
>         <a name="engg"> 
>             <b item="pc"/> 
>             <b item="backpack"/> 
>         </a> 
>     </a> 
>     .... 
>     ... 
> </xyz> 
> 
> 
> Now, from this XML document I want to create a HTML
document which would be
> a list of all the 'b' element's attributes 
> (i.e. item). As you see there are a few items which
are repeated in the XML
> document. If I want only the unique elements 
> depending on b's attribute item then how should go
about writing the XSLT
> template. Is this possible? Maybe I have to parse 
> the entire document more than once to see if a
particular node is unique,
> but how to do this? Any help!!! 
> 
> 
> PS: I am using  XT (Ver 19990822) by James Clark for
the transformation. 
> 
> 
> Thank you, 
> Anand 
> 
>  

__________________________________________________
Do You Yahoo!?
Bid and sell for free at http://auctions.yahoo.com


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread