Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Auto generated index based on category fields 1

Status
Not open for further replies.

boozer159

Technical User
Feb 19, 2008
2
GB
Has anyone ever faced this?:

I'm trying to automatically generate and index/tableofcontents based on categories applied to each entry. Here's my example XML:

<root>
<row pagename="page1" cat1="a" cat2="b" cat3="c" cat4="d" />
<row pagename="page2" cat1="b" cat2="f" cat3="c" cat4="" />
<row pagename="page3" cat1="c" cat2="f" cat3="a" cat4="" />
<row pagename="page4" cat1="f" cat2="e" cat3="a" cat4="g" />
<row pagename="page5" cat1="g" cat2="" cat3="" cat4="" />
<row pagename="page6" cat1="c" cat2="d" cat3="b" cat4="" />
</root>

The output I'm trying to get is a list by category, such as:

a
page1
page3
page4
b
page1
page2
page6
c
page1
page2
page3
page6
d
page1
page6
e
page4
f
page2
page3
page4
g
page4
page5

I'm using MSXML4 to process (less said the better...) and unfortunately am stuck with XSLT1.0.

Here's the XSL I've written so far:

<xsl:key name="indexbytopic" match="/root/row" use="@cat1 | @cat2 | @cat3 | @cat4"/>

<xsl:template match="/root">

<ul>
<xsl:for-each select="row[count(. | key('indexbytopic', @cat1 | @cat2 | @cat3 | @cat4)[1]) = 1]">
<xsl:sort select="@cat1 | @cat2 | @cat3 | @cat4" />
<li><xsl:value-of select="@cat1 | @cat2 | @cat3 | @cat4" />
<ul>

<xsl:call-template name="items" />

</ul></li>
</xsl:for-each>
</ul>

</div>
</div>
</xsl:template>

<xsl:template name="items">
<xsl:for-each select="key('indexbytopic', @cat1 | @cat2 | @cat3 | @cat4)">
<xsl:sort select="." />
<li><xsl:value-of select="@pagename" /></li>
</xsl:for-each>

</xsl:template>

If someone could tell me where I'm going wrong, or give me some suggestions I'd appreciate it.

Thanks,

Booze
 
Have tried that previously, although all went to pieces when I started using more than one attribute. Using the M method works fine when what you're grouping by one node or attribute with subgroups, but I've got 5 per row - each being as important as each other.
A quick retry of the method gave me:


a
b
b
f
c
d
f
f
e
g

Any other thoughts?
 
Any other thoughts?

I made the reasonable assumption that the same value would not appear in more than one of the catn attributes for any given row.

Code:
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
<xsl:output method="text"/>
<xsl:variable name="newline"><xsl:text>
</xsl:text>
</xsl:variable>
<!-- index all the attributes whose name begins with 'cat'
     which are subordinate to a row element -->
<xsl:key name="indexbycat" match="//row/@*[substring(local-name(),1,3)='cat']" use="." />  

<xsl:template match="/">
    <!-- The outer for-each selects the first attribute node 
         for every unique attribute value which is not a zero-length
         string.  In other words, the outer for-each will iterate 
         exactly once for each unique value of the 'cat?' attributes. -->  
    <xsl:for-each select="//row/@*[generate-id(.)=generate-id(key('indexbycat', .)[1]) 
                                    and . != '']">
      <xsl:sort select="."/>
      <xsl:variable name="indexValue" select="."/>
      <xsl:value-of select="concat('Category: ', $indexValue, $newline)"/>
      <!-- The inner for-each iterates over all attributes that match 
           the outer for-each attribute value -->
      <xsl:for-each select="key('indexbycat', $indexValue)">
        <xsl:sort select="../@pagename"/>
        <xsl:value-of select="concat('    ', ../@pagename, $newline)"/>
      </xsl:for-each>
      <xsl:value-of select="$newline"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Code:
Category: a
    page1
    page3
    page4

Category: b
    page1
    page2
    page6

Category: c
    page1
    page2
    page3
    page6

Category: d
    page1
    page6

Category: e
    page4

Category: f
    page2
    page3
    page4

Category: g
    page4
    page5

Tom Morrison
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top