Search code examples
xslt-2.0xsl-fo

position() function is not working XSLT2.0 FOP2.8


I am trying to fetch the data from xml based upon the position below is the sample xml

<node>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value3]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value4]]></ItemValue>
  </Item>
  <Item>
   <ItemName><![CDATA[Name]]></ItemName>
   <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
</node>

Now I want to get that value3 and value4 to be fetched and concatenated based upon the position

This is my sample logic in xslt for the same;

 <xsl:for-each select="node/Item">
     <xsl:variable name="cellValue">
        <xsl:if test="(ItemValue != '')">
           <xsl:when test ="position() = 4"/> <!--will skip as it is getting concatenated with pos() 3-->
           <xsl:when test ="position() = 3">
             <xsl:value-of select="concat(ItemValue,node/Item[position()+1]/ItemValue)"/>
           </xsl:when>
           <xsl:otherwise>
             <xsl:value-of select="ItemValue"/>
           </xsl:otherwise>
        </xsl:if>
     </xsl:variable>

    <xsl:if test="$cellValue != ''">
     <fo:table-row>
      <fo:table-cell>
         <fo:block>
            <xsl:value-of select="$cellValue"/>
         </fo:block>
      </fo:table-cell>
     </fo:table-row>
    </xsl:if>
    
  </xsl:for-each>

Name space i am using

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fn="https://www.w3.org/2005/xpath-functions"
                xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                xmlns:xalan="http://xml.apache.org/xalan"
                xmlns:fox="http://xml.apache.org/fop/extensions"
                xmlns:pre="xalan://org.apache.xalan.Version"
                xmlns:svg="http://www.w3.org/2000/svg">

But I am seeing that value3 and value4 is not getting populated in my output pdf

Update

Sorry for being inconvenient:

Updated the xml hierarchy format

[Unfortunately you haven't explained what your code is supposed to do..]

**Here I am trying to get the values from elements matching xpath:

node/Item/ItemValue

ItemValue (s) are not static; only assurity is that for the index 3 and 4; which are Item[3] and Item[4]; we always need to concatenate these ItemValue (s). And rest ItemValues can be as it is. Hence I was using position() function to evaluate the positions of each

node/Item

what will be the possible solution then?

[You seem to have misunderstood what the position() function does.]

**If possible can you please give a brief idea about the use case of position?


Solution

  • You can use the following-sibling::*[1] axis like this:

    <xsl:variable name="cellValue">
      <xsl:if test="(ItemValue != '')">
        <xsl:choose>
          <xsl:when test ="position() = 4"/> <!--will skip as it is getting concatenated with pos() 3-->
          <xsl:when test ="position() = 3">
            <xsl:value-of select="concat(ItemValue,  following-sibling::Item[1]/ItemValue)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="ItemValue"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:variable>
    

    the predicate [1] means only the first