0

I have to select the values based on conditions. If Author name = Bero, it should display roles of 1st author, if Author name= Aurora it should display all topics.But I'm not getting expected output. Here is my XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:regexp="http://exslt.org/regular-expressions"
   version="1.0">
   <xsl:template match="/">
      <xsl:variable name="Store">
         <Bookstore>
            <Author name="Bero">
               <topic>Athletics</topic>
            </Author>
            <Author name="ABC">
               <topic>Sports</topic>
            </Author>
         </Bookstore>
      </xsl:variable>
      <xsl:for-each select="$Store/Bookstore/Author">
         <xsl:choose>
            <xsl:when test="contains($Author ='Bero')">
               <xsl:variable name="Store" select="string($Store/Bookstore/Author[@name='Aurora']/u/text())"/>
            </xsl:when>
            <xsl:when test="contains($Author ='Aurora')">
               <xsl:variable name="Store" select="string($Store/Bookstore/Author[@name='Aurora'and @name='Bero']/u/text())"/>
            </xsl:when>
         </xsl:choose>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

Expected Partial Output1 when 1st test case is executed:

<topic>Athletics</topic>
       

Expected Partial Output2:

<topic>Athletics</topic>
 <topic>Sports</topic>
GeetaG
  • 7
  • 5
  • If that XSLT 1 code would really be run by an XSLT 1 processor I would `` expect to give an error about trying to use a result tree fragment as a node-set. – Martin Honnen Dec 08 '20 at 13:55

1 Answers1

1

You're treating variables as you would in a procedural language. See for example xslt variable scope and its usage for a better understanding of why this doesn't work.

You're making two basic errors:

  • xsl:for-each is a functional mapping, not a loop. Think of it as processing all the selected items in parallel. The way you process one item can't have any effect on the way you process subsequent items

  • xsl:variable is a variable binding, not an assignment. Each xsl:variable instruction creates a new variable, it doesn't modify the value of other existing variables even if they have the same name. And when the xsl:variable instruction is the only thing inside xsl:when, then it has no effect at all, because the new variable disappears as soon as it is created.

Any good XSLT textbook will explain these concepts for you.

In addition, the condition <xsl:when test="contains($Author ='Bero')"> makes no sense. There's no variable named $Author, and if there was, the contains() function expects two string-valued arguments whereas you have supplied a single boolean argument.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164