Hodor
Hodor

Reputation: 9

XSLT if matching all XML tag contents

Problem : Given an xml file, get the value of content/id tag with value 'sam' using xslt

Issue: All the values matching the same path getting selected. Both brian and sam.

(I wondered the select should select the first match and shouldn't loop like for-each utility provided in xslt)

xml:

<?xml version="1.0" encoding="UTF-8"?>
<Primary>
  <PID>Tech1</PID>
  <Version>1234</Version>
  <AData>
      <Id>widnows</Id>
 </AData>
 <BData>
   <Content>
      <Id>brian</Id>
   </Content>
   <Content>
      <Id>sam</Id>
   </Content>
 </BData>
</Primary>`

xslt

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
  <xsl:template match="/Primary">
    <xsl:variable name="var" select="'sam'" />
     <xsl:apply-templates select="BData/Content">
         <xsl:if test="Id='sam'">
         <xsl:value-of select="Id"/>
         </xsl:if>
    </xsl:apply-templates>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 1283

Answers (1)

Tim C
Tim C

Reputation: 70598

You currently have an xsl:if statement as a child of xsl:apply-templates which is not allowed in XSLT. If you only want to select Content elements with an Id value of "sam", you can put the condition in the select attribute of apply-templates, like so

<xsl:apply-templates select="BData/Content[Id='sam']" />

Try something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
  <xsl:template match="/Primary">
     <xsl:variable name="var" select="'sam'" />
     <xsl:apply-templates select="BData/Content[Id=$var]" />
  </xsl:template>

  <xsl:template match="Content">
      <xsl:value-of select="Id" />
  </xsl:template>
</xsl:stylesheet>

EDIT: The expression within the square brackets does not have to be just equals, it can be any valid expression, for example, if you wanted only Content elements whose Id started with "sam" or "bob", you would do this:

 <xsl:apply-templates select="BData/Content[starts-with(Id, 'sam') or starts-with(Id, 'bob')]" />

Upvotes: 1

Related Questions