How to check if element node contains a specific value in xsl
Asked Answered
O

2

5

I have an XML document:

<?xml version="1.0" encoding="ISO-8859-1"?>
<document>
    <fruits>
        <fruit id="1">
            <title>I like pineapples</title>
            <description> a tropical plant with edible multiple fruit consisting of coalesced berries</description>
        </fruit>
        <fruit id="2">
            <title>I like watermelons</title>
            <description>has a smooth exterior rind (green, yellow and sometimes white) and a juicy, sweet interior flesh</description>
        </fruit>
    </fruits>
</document>

How do I check if the title element contains 'pineapple' so that i can only display description for that particular fruit ?

Here is the XSLT transformation I have:

<?xml version="1.0" encoding="iso-8859-1"?>

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

  <xsl:output  method="xml" omit-xml-declaration="yes" doctype-public="-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
             doctype-system="http://www.wapforum.org/DTD/xhtml-mobile10.dtd"/>
 <xsl:template match="/">
    <xsl:element name="html">
      <xsl:element name="head">        
        <xsl:element name="title">Fruits</xsl:element>
      </xsl:element>

      <xsl:element name="body">
        <xsl:if test="/document/fruits/fruit/title[contains(text(),'pineapple')]">
          <xsl:value-of select="description"/>
        </xsl:if>
        </xsl:element>
    </xsl:element>
  </xsl:template>
 </xsl:stylesheet>
Ortego answered 7/4, 2013 at 12:59 Comment(9)
Have you considered using a predicate like [contains(text(),'pineapple')] for title elements?Foskett
I've tried <xsl:if test="/document/fruis/fruit/title[contains(text(),'pineapple')]">Ortego
In your expression, it should be fruits instead of fruis. And your xml is not well formed, the <fruits> and <fruit> elements are not properly closed. If you fix these, I think it will work.Foskett
@Foskett no, i've corrected the mistakes in xml and <xsl:if> and tested it again but it doesn't work.Ortego
I tested the XPath expression using the tool and it works fine. I think there might be a problem in the XSLT code. Could you show all the related elements in the XSLT?Foskett
@Foskett Please check my XSLT code I've added above. ThanksOrtego
Is the stylesheet correctly linked to the xml?Foskett
I suspect the line <xsl:value-of select="description"/> might be the culprit. Try to put the if in a for-each with a select fruit (the parent of both title and description).Foskett
yes it is correctly linked.Ortego
S
9

Here's a slightly more push-driven approach that accomplishes what you want.

When this XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"
  doctype-public="-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
  doctype-system="http://www.wapforum.org/DTD/xhtml-mobile10.dtd" />
  <xsl:strip-space elements="*" />

  <xsl:template match="/*">
    <html>
      <head>
        <title>Fruits</title>
      </head>
      <body>
        <xsl:apply-templates
          select="fruits/fruit[contains(title, 'pineapple')]" />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="fruit">
    <xsl:apply-templates select="description" />
  </xsl:template>
</xsl:stylesheet>

...is applied to the provided XML:

<?xml version="1.0" encoding="utf-8"?>
<document>
  <fruits>
    <fruit id="1">
      <title>I like pineapples</title>
      <description>a tropical plant with edible multiple fruit
      consisting of coalesced berries</description>
    </fruit>
    <fruit id="2">
      <title>I like watermelons</title>
      <description>has a smooth exterior rind (green, yellow and
      sometimes white) and a juicy, sweet interior
      flesh</description>
    </fruit>
  </fruits>
</document>

...the wanted result is produced:

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Fruits</title>
  </head>
  <body>a tropical plant with edible multiple fruit consisting of coalesced berries</body>
</html>
Settler answered 7/4, 2013 at 15:44 Comment(4)
This solution kind of works but it also displays the title and descritpion for watermelon. The result produced is: a tropical plant with edible multiple fruit consisting of coalesced berries I like watermelonshas a smooth exterior rind (green, yellow and sometimes white) and a juicy, sweet interior fleshOrtego
What XSLT processor are you using? I've used several (Expat, Saxon, libxslt, etc.) and do not get the results you're seeing.Settler
Ok Sorry! your solution worked, the solution by @Dimitre Novatchev caused that result.Ortego
@Sujal, Yes, there was a single line missing in my answer, which is now in place.Reflex
R
2

A simpler and almost fully "push style" solution:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
    <html>
      <head>
        <title>Fruits</title>
      </head>
      <body><xsl:apply-templates/></body>
    </html>
 </xsl:template>

 <xsl:template match="fruit[contains(title, 'pineapple')]">
  <xsl:value-of select="description"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<document>
    <fruits>
        <fruit id="1">
            <title>I like pineapples</title>
            <description> a tropical plant with edible multiple fruit consisting of coalesced berries</description>
        </fruit>
        <fruit id="2">
            <title>I like watermelons</title>
            <description>has a smooth exterior rind (green, yellow and sometimes white) and a juicy, sweet interior flesh</description>
        </fruit>
    </fruits>
</document>

the wanted, correct result is produced:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

      <title>Fruits</title>
   </head>
   <body> a tropical plant with edible multiple fruit consisting of coalesced berries</body>
</html>
Reflex answered 7/4, 2013 at 16:19 Comment(2)
This solution kind of works but it also displays the title and descritpion for watermelon. The result produced is: a tropical plant with edible multiple fruit consisting of coalesced berries I like watermelonshas a smooth exterior rind (green, yellow and sometimes white) and a juicy, sweet interior fleshOrtego
@Sujal, Sorry, there was a minor copy+paste issue. Corrected now.Reflex

© 2022 - 2024 — McMap. All rights reserved.