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 September 13th, 2005, 06:58 PM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default xsl question

I am having a problem making an xslt template to pase a small xml file I have.

I am passing the xslt file one parameter. I want to use this parameter to match a node that has the parameter in it then loop through its children.

the xml file looks like this.

<HEADER>
    <LINK name="Education">
        <TITLE>HighSchool</TITLE>
        <URL>/Intrests.aspx</URL>
        <TITLE>Bachelors</TITLE>
        <URL>/Projects.aspx</URL>
        <TITLE>Masters</TITLE>
        <URL>/Projects.aspx</URL>
        <TITLE>Certifications</TITLE>
        <URL>/Projects.aspx</URL>
    </LINK>
    <LINK name="Home"></LINK>
    <LINK name="Interests"></LINK>
    <LINK name="Contact"></LINK>
    <LINK name="Project"></LINK>
    <LINK name="Work"></LINK>
    <LINK name="About Site"></LINK>
</HEADER>

I want to use my passed in parameter to match the name attribute of the link node and loop through the TITLE and URL elements within that node.

I was trying something like this without much luck.

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


    <xsl:param name="LINK" select="Education"></xsl:param>
    <xsl:for-each select="//HEADER/LINK/@name">
        <xsl:if test="@name=$LINK">
        <xsl:for-each select="//HEADER/LINK/TITLE">
        <a>
      <xsl:attribute name="HREF">test<xsl:value-of select="TITLE"/>test</xsl:attribute>
      <xsl:value-of select="@name" />

      </a>
        </xsl:for-each>
        </xsl:if>
     </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

I know the loops above don't exactly make sense right now because I have been changing them so much but I can't get anything I try to work. I am setting the parameter "LINK" above to Education just for testing purposes.

Is there a better way to do this istead of using 2 loops?

Any help would be much apreciated.


 
Old September 14th, 2005, 02:27 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Try to avoid using // in paths, it's an expensive process to select all nodes in the document when you know what level they are at anyway.
Your main problem is that your param defaults to Education, i.e. the XSLT tries to evaluate Education as a node test not a string, you need 'Education'. Your search logic can also be simplified, try this:
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="LINK" select="'Education'" />

  <xsl:template match="/">   
    <xsl:apply-templates select="HEADER/LINK[@name = $LINK]" />
  </xsl:template>

  <xsl:template match="LINK">
    <h3><xsl:value-of select="@name" /></h3>
    <xsl:apply-templates select="TITLE" />
  </xsl:template>

  <xsl:template match="TITLE">
    <a href="{following-sibling::URL[1]}"><xsl:value-of select="." /></a>  
  </xsl:template>
</xsl:stylesheet>
I think your XML would be easier to manage if you had thius sort of thing:
Code:
  <LINKS name="Education">
    <LINK><TITLE>HighSchool</TITLE>
      <URL>/Intrests.aspx</URL>
    </LINK>
    <LINK><TITLE>Bachelors</TITLE>
      <URL>/Projects.aspx</URL>
    </LINK>
    <LINK><TITLE>Masters</TITLE>
      <URL>/Projects.aspx</URL>
    </LINK>
    <LINK><TITLE>Certifications</TITLE>
      <URL>/Projects.aspx</URL>
    </LINK>
  </LINKS>

--

Joe (Microsoft MVP - XML)
 
Old September 14th, 2005, 03:15 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

You haven't understood the concept that xsl:for-each changes the context node, and relative path expressions start from the context node.

    <xsl:for-each select="//HEADER/LINK/@name">

This means that the context node is now an attribute, the @name attribute. (Also note, HEADER is the outermost element of your document, so you don't need to search the whole document to find it. Use /HEADER rather than //HEADER).

        <xsl:if test="@name=$LINK">

@name is a relative path expression, it looks for an attributes of the context node called name. But attributes don't have attributes, so it won't find one. You want test=". = $LINK".

        <xsl:for-each select="//HEADER/LINK/TITLE">

This is a so-called "absolute path expression". It doesn't start from the context node, it starts from the root. So you're selecting all the TITLE elements, not just the one for the selected LINK. You want the TITLEs of the LINK that's the parent of the selected attribute: select="../TITLE". Or most people would do it like this:

<xsl:for-each select="/HEADER/LINK[@name=$LINK]">
        <a>
      <xsl:attribute name="HREF">test<xsl:value-of select="TITLE"/>test</xsl:attribute>
      <xsl:value-of select="@name" />

      </a>
 </xsl:for-each>

Go back to the spec or your favourite reference book, and reread the section about the context node.



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old September 14th, 2005, 09:19 AM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks alot,

After reading your comments I decided to go through the w3schools xslt refrence. Everything makes much more sense now.

 
Old September 14th, 2005, 01:22 PM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I still am not able to get exactly what I want.

I did change my xml format to the suggestion from above and I tried many variations on the xsl that both of you guys posted. The xsl that you guys posted only returned the top link after the LINKS element with the matching name attribute. I want to display all of the LINK elements.

It seemed logical to me that this would do exactly what I want.

 <xsl:template match="/">
    <html>
    <body>
    <xsl:apply-templates select="HEADER/LINKS[@name = $LINK]" />
    <xsl:for-each select="LINK">
    <a>
      <xsl:attribute name="HREF"><xsl:value-of select="TITLE"/>test
      </xsl:attribute>
      </a>
      </xsl:for-each>
    </body>
     </html>
  </xsl:template>

The xsl above sends out all of the TITLES and all of the URLS and it doesn't format them into html href links.

Waht is going on here?

 
Old September 14th, 2005, 01:48 PM
Registered User
 
Join Date: Sep 2005
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I finally got something to do exactly what I was looking for. Thanks for all the help.

 
Old September 14th, 2005, 05:18 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

The root node "/" can either have a HEADER child or a LINK child but it can't have both. You've got an apply-templates that assumes it has a HEADER child, and a for-each that assumes it has a LINK child.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old September 15th, 2005, 01:34 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Quote:
quote:Originally posted by bluisana
 I still am not able to get exactly what I want.

The xsl that you guys posted only returned the top link after the LINKS element with the matching name attribute. I want to display all of the LINK elements.
Are you sure about this? I tested the XSLT and it returned all the links for a section given the original format.

--

Joe (Microsoft MVP - XML)





Similar Threads
Thread Thread Starter Forum Replies Last Post
xsl question for new user MHTL XSLT 4 May 13th, 2008 10:01 PM
XSL newbie question Someone2006 XSLT 4 October 10th, 2006 07:20 AM
xsl:sort Question kwilliams XSLT 6 July 18th, 2005 08:39 AM
xsl:if question rdavisiii XSLT 2 March 30th, 2005 01:40 PM
XSL processing question.. eladner XSLT 1 August 24th, 2004 07:58 AM





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