Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 20th, 2007, 12:25 PM
Registered User
 
Join Date: Jul 2007
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default Retrieve numbered node path from xml

Hello,

I am a newbie to XSLT. After numerous attempts to accomplish this task using .NET methods, I am wondering if XSLT might be the solution. I've searched on this forum and found some similar problems, but nothing quite like what I'm facing.

What I'm trying to do is create a website breadcrumb control that shows the heirarchical path from a root node to the current selected node (this tree will be displayed in a left nav which the user can select links in) in the navigation tree. In addition, each node needs to be numbered in accordance with its position in the tree (I will describe that part after describing the xml). Here is the xml sitemap structure:

<?xml version="1.0" encoding="utf-8" ?>

<sitemap>
  <navigation>
    <nav id="title1">
      <title>Title 1</title>
      <section>1</section>
      <description></description>
      <stylesheet></stylesheet>
      <nav id="title2">
        <title>Title 2</title>
        <description></description>
      </nav>
    </nav>
    <nav id="title3">
      <title>Title 3</title>
      <section>2</section>
      <description></description>
      <nav type="descriptor">
        <title>Descriptor Title</title>
        <description></description>
      </nav>
      <nav id="title4">
        <title>Title 4</title>
        <description></description>
        <nav id="title5">
          <title>Title 5</title>
          <description></description>
        </nav>
        <nav id ="title4">
          <title>Title 4</title>
          <description></description>
        </nav>
        <nav id ="title5">
          <title>Title 5</title>
          <description></description>
        </nav>
        <nav id ="title6">
          <title>Title 6</title>
          <description></description>
        </nav>
      </nav>
    </nav>
    <nav id="title7">
      <title>Title 7</title>
      <section>3</section>
      <description></description>
    </nav>
  </navigation>
</sitemap>

So for example, if the user were to click on "Title 6" (hopefully the dummy titles don't confuse things here), the desired output would be: "2.0 Title3 > 2.1 Title4 > 2.1.4 Title6". So the numbering begins with the section number, then another number gets appended for each child 'step' required to find the desired node (and incremented as each sibling is passed by). One note is that only nodes with an id attribute should be counted (so the node with attribute type="descriptor" would not be counted).

I hope this makes sense. I thought originally that I could use embedded for-each loops to achieve my desired result, but no luck with that- as an alternative I'm wondering if it's possible to start with the target node and use count(preceding-sibling) in combination with parent to count backwards to the root node.

Any ideas or feedback are much appreciated. Please let me know if I need to clarify more.

Thanks much in advance!

Jeff
 
Old July 20th, 2007, 12:49 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Looks like:

<xsl:apply-templates select="ancestor::nav" mode="breadcrumb"/>

with

<xsl:template match="nav" mode="breadcrumb">
  <xsl:number level="multiple" count="nav[@id]"/>
  <xsl:value-of select="title"/>
</xsl:template>

plus a bit of punctuation thrown in.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old July 20th, 2007, 02:20 PM
Registered User
 
Join Date: Jul 2007
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Michael,

Thanks so much for your response.

Please forgive my ignorance here, but I'm not having any luck implementing this xsl. Would the final xsl look like this?

I failed to mention before that the desired (clicked) id would (in my mind) be passed in as a parameter. One other thing- I don't think it is of consequence, but perhaps I should mention that I am doing an xsl transform using .net on the xml file.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" encoding="UTF-8" />
  <xsl:param name="id"></xsl:param>
  <xsl:template match="/">

      <xsl:apply-templates select="ancestor::nav" mode="breadcrumb"/>

  </xsl:template>
  <xsl:template match="nav" mode="breadcrumb">
    <xsl:number level="multiple" count="nav[@id]"/>
    <xsl:value-of select="title"/>
  </xsl:template>
</xsl:stylesheet>

Thanks once again, I truly appreciate your help.

Jeff

 
Old July 20th, 2007, 02:56 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I was assuming that you were starting at the <nav> element that you want to number, and that you would want to integrate this into a bigger stylesheet. So something like

<xsl:apply-templates
select="//nav[@id=$id]/ancestor::nav" mode="breadcrumb"/>

But I don't see how you intend this to work since your id values aren't unique.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old July 20th, 2007, 03:25 PM
Registered User
 
Join Date: Jul 2007
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Once again thanks for your reply.

This is working almost perfectly now- the only thing that isn't is that I'm not getting the final 'piece' of the breadcrumb, that is, the actual node that was clicked on.

I am, however, getting the beautifully numbered path up to that node.

Thanks so much for your help on this.

Jeff


 
Old July 20th, 2007, 03:32 PM
Registered User
 
Join Date: Jul 2007
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Apologies- just added the line:

<xsl:apply-templates select="//nav[@id=$id]" mode="breadcrumb"/>

below the first apply-templates line and am now getting the desired result. There may be a better way of doing this but it's working great for now.

Thank you Michael, I very much appreciate your helpful responses!

Jeff

 
Old July 20th, 2007, 03:59 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Try ancestor-or-self::nav instead of ancestor::nav

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Retrieve Active File Path francois.timms Excel VBA 3 March 24th, 2008 05:14 PM
How Retrieve data of a node or from an element chandu.mca007 XML 1 December 16th, 2006 03:11 PM
Retrieve the escaped node content carlos.bravo XSLT 4 September 16th, 2005 03:23 PM
Parameter value as node path, doesn't work scubaduba XSLT 2 November 6th, 2004 02:15 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.