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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xsl variable scope

Status
Not open for further replies.

darkstarbg

Technical User
Jun 20, 2005
3
BG
Hello, I'm trying to make a DVD catalog but I'm having problems extracting data from my XML file using the id values and a variable. I'm going to post the source files first to make clear exactly what I'm trying to achieve.

XML file:

<?xml version="1.0" encoding="windows-1251"?>
<?xml-stylesheet type="text/xsl" href="catalog_director_tests2.xsl"?>
<catalog>

<dvds>
<dvd id="1">
<title>????? ????????? ?? ????????</title>
<price>24.99$</price>
<director>1</director>
<year>2001</year>
<description>National Geographic Beyond the Movie The Lord of the Rings - The Fellowship of the Ring</description>
</dvd>

<dvd id="2">
<title>????????? ?? ???????? - ????????? ?????????????? ???????</title>
<price>64.99$</price>
<director>1</director>
<year>2001</year>
<description>Platinum Series Special Extended Edition Collector's Gift Set (2001)</description>
</dvd>

<dvd id="3">
<title>????????? ?? ???????? ?? ?????? - ???????</title>
<price>13.99$</price>
<director>1</director>
<year>2001</year>
<description>Secrets of Middle-Earth: Inside Tolkien's The Fellowship of the Rings</description>
</dvd>

<dvd id="4">
<title>??????????? ?? ????? ?? ?????? - ???????</title>
<price>13.99$</price>
<director>1</director>
<year>2004</year>
<description>Secrets of Middle-Earth: Inside Tolkien's The Return of the King </description>
</dvd>


<directors>

<director id="2">
<name>George Lucas</name>
</director>

<director id="1">
<name>Peter Jackson</name>
</director>



</directors>

</catalog>



XSL file:

<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="
<xsl:template match="/">


<xsl:for-each select="catalog/directors/director">

<xsl:if test="name = 'Peter Jackson'">
<xsl:variable name="dname" select="@id"/>
<xsl:value-of select="$dname"/>
</xsl:if>

</xsl:for-each>



<html>
<body>
<h2>catalog 2</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Price</th>
</tr>
<xsl:for-each select="catalog/dvds/dvd">
<xsl:sort select="price"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="@id"/></td>
</tr>
</xsl:for-each>
</table>


<h2>?????????</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>ID</th>
<th>???</th>
</tr>
<xsl:for-each select="catalog/directors/director">
<xsl:if test="name= 'Peter Jackson'">
<tr>
<td><xsl:value-of select="@id"/></td>
<td><xsl:value-of select="name"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>

</body>
</html>
</xsl:template>

</xsl:stylesheet>

The problem is that I can't use the $dname variable outside of the for-each block as it loses scope. I need it so that I can associate a movie with its director. How can I make this variable global? When I declare it otside xsl:template I recieve an error message: Keyword xsl:stylesheet may not contain xsl:for-each. How can I go arround this?
 
Not entirely sure what you mean, but generally you don't need to use variables. Also, its better practice to use templates instead of for-each:
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]

  <xsl:template match="/">
    <html>
      <body>
        <h2>catalog 2</h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Director</th>
            <th>Price</th>
          </tr>
          <xsl:apply-templates select="catalog/dvds/dvd">
            <xsl:sort select="price"/>
          </xsl:apply-templates>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="dvd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="../../directors/director[@id = current()/director]/name"/></td>
      <td><xsl:value-of select="price"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

Jon

"Asteroids do not concern me, Admiral. I want that ship, not excuses.
 
Thank you for your answer. This works for the sort by price xsl file but I also need to extract movie titles by the director's name. In this case I have to use for-each but instead of xsl:sort because I don't need to sort the results. That is why I used a variable in my example. Can I achieve this without useing a varible. For example can I extract only the movies directed by Peter Jackson without using a variable?
 
I'd probably do something like this:
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:param name="director" select="'Peter Jackson'"/>
  <xsl:template match="/">
    <html>
      <body>
        <h2>catalog 2</h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Director</th>
            <th>Price</th>
          </tr>
          <xsl:apply-templates select="catalog/dvds/dvd" mode="all">
            <xsl:sort select="price"/>
          </xsl:apply-templates>
        </table>
        <h2>
          <xsl:text>Films by </xsl:text>
          <xsl:value-of select="$director"/>
        </h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Price</th>
          </tr>
          <xsl:apply-templates select="catalog/dvds/dvd[director = ../../directors/director[name = $director]/@id]" mode="byDirector">
            <xsl:sort select="price"/>
          </xsl:apply-templates>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="dvd" mode="all">
    <tr>
      <td>
        <xsl:value-of select="title"/>
      </td>
      <td>
        <xsl:value-of select="../../directors/director[@id = current()/director]/name"/>
      </td>
      <td>
        <xsl:value-of select="price"/>
      </td>
    </tr>
  </xsl:template>
  <xsl:template match="dvd" mode="byDirector">
    <tr>
      <td>
        <xsl:value-of select="title"/>
      </td>
      <td>
        <xsl:value-of select="price"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

Jon

"Asteroids do not concern me, Admiral. I want that ship, not excuses.
 
I described the Scope of variables in this thread:
thread426-1063382

Visit My Site
PROGRAMMER: (n) Red-eyed, mumbling mammal capable of conversing with inanimate objects.
 
Thank you very much for your answers! :) You've been very helpful!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top