Rito Sarkar
Rito Sarkar

Reputation: 69

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?

Upvotes: 0

Views: 65

Answers (2)

Siebe Jongebloed
Siebe Jongebloed

Reputation: 4870

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

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163595

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

Unfortunately you haven't explained what your code is supposed to do, and it's hard to reverse engineer your requirements from code that doesn't meet them.

You include the code fragment node/Item[position()+1]. This won't select anything. Firstly, the context is an Item element, and your Item element does not have a child called node. Perhaps you meant parent::node. Secondly a numeric predicate P is short for [position()=P], so your predicate means [position()=position()+1] which will never be true. Perhaps you meant following-sibling::Item.

Upvotes: 0

Related Questions