Haritz
Haritz

Reputation: 1752

XSL Transformation and XPath

I am developing an application were I need to transform XML documents that look like this:

<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE words SYSTEM "words.dtd">
<words>
<word id="word_1">Alfa</word>
<word id="word_2">Beta</word>
<word id="word_3">Gamma</word>
<word id="word_4">Delta</word>
<word id="word_5">Zeta</word>
</words>

Using a XSLT stylesheet. I would like the result of the transformation to be (in this case) Delta and this is the XSL I am using:

<?xml version='1.0' encoding='ISO-8859-1'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="Hurrengo_Hitza">word_4</xsl:param>
    <xsl:template match="word/[@id = Hurrengo_Hitza]">
  <html>
  <body>
    <tr>
      <td><xsl:value-of select="text()"/></td>
    </tr>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

It shows no result, what do I have to change in the XSLT? Something wrong in the XPath expression?

Upvotes: 1

Views: 924

Answers (3)

rt2800
rt2800

Reputation: 3045

Change

<xsl:template match="word/[@id = Hurrengo_Hitza]"> 

to

<xsl:template match="word/[@id = $Hurrengo_Hitza]">

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

There are two problems here:

  1. word/[@id = Hurrengo_Hitza] is syntactically invalid XPath -- a predicate showld follow a node-test within a location step.

  2. <xsl:template match="word/[@id = Hurrengo_Hitza]"> . Even if corrected to <xsl:template match="word[@id = Hurrengo_Hitza]"> which is now syntactically valid XPath expression and match pattern, this template doesn't match any node -- it matches any word the string value of whose id attribute is equal to the string valu of one of its Hurrengo_Hitza elements. However no word element in the provided XML document has a child element named Hurrengo_Hitza -- therefore the template doesn't match any node and will not be executed at all.

Solution:

What you want is a match pattern like: word[@id = $Hurrengo_Hitza] -- a variable or parameter reference must start with the $ character.

If you change:

<xsl:template match="word/[@id = Hurrengo_Hitza]"> 

to:

<xsl:template match="word[@id = $Hurrengo_Hitza]"> 

you'll have a working XSLT 2.0 solution.

However, in XSLT 1.0 (which you seem to be using), it is illegal to have a variable or parameter reference within a match pattern.

An XSLT solution, therefore will be something like this:

<xsl:template match="word">
  <xsl:if test="@id = $Hurrengo_Hitza">
   <!-- Processing here -->
  </xsl:if> 
</xsl:template>

Upvotes: 3

filype
filype

Reputation: 8380

The param in XSLT needs to be preceded by a dolar sign ($)

So try:

<xsl:template match="word[@id = $Hurrengo_Hitza]">

UPDATE:

I think you are only allowed variables on the match attribute on XSLT 2.

But here is how you could do it:

<xsl:param name="Hurrengo_Hitza" select="'word_4'" />

<xsl:template match="/">
        <xsl:for-each select="//word[@id = $Hurrengo_Hitza]">
          <html>
          <body>
            <tr>
              <td><xsl:value-of select="text()"/></td>
            </tr>
          </body>
          </html>
        </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions