user2586047
user2586047

Reputation: 1

How to use regular expression for xpath of XML in xslt?

I have my XML as below:

<pi:Additional_Information>
 <pi:Allocation_Cost_Center_1 > test value cost 1 </pi:Allocation_Cost_Center_1>
 <pi:Allocation_Cost_Center_2 > test value cost 2 </pi:Allocation_Cost_Center_2>
 <pi:Allocation_Cost_Center_3 > test value cost 3 </pi:Allocation_Cost_Center_2>
 <pi:Allocation_Cost_Center_4 > test value cost 4 </pi:Allocation_Cost_Center_2>
 <pi:Allocation_Region_1 >test value region 1</pi:Allocation_Region_1>
 <pi:Allocation_Region_2 >test value region 2</pi:Allocation_Region_2>
 <pi:Allocation_Region_3 >test value region 3</pi:Allocation_Region_3>
 <pi:Allocation_Region_4 >test value region 4</pi:Allocation_Region_4>
 <pi:Allocation_Location_1>Berlin</pi:Allocation_Location_1>
 <pi:Allocation_Location_2>Berlin</pi:Allocation_Location_2>
 <pi:Allocation_Location_3>Berlin</pi:Allocation_Location_3>
 <pi:Allocation_Location_4>Berlin</pi:Allocation_Location_4>
</pi:Additional_Information>

I need to loop through all the tags ending with one in first loop, in next loop all tags ending in 2 and so on.....

I am using XSLT 2.0. Expected output is as below:

(Row one)

test value cost 1 test value region 1 Berlin

(Row two)

test value cost 2 test value region 2 Berlin

(Row three)

test value cost 3 test value region 3 Berlin

(Row four)

test value cost 4 test value region 4 Berlin

Thanks in advance.

Upvotes: 0

Views: 239

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117100

Here's another way you could look at it:

<xsl:template match="/pi:Additional_Information">
    <xsl:variable name="nodes" select="*" />
    <xsl:variable name="rows" select="count($nodes) div 3" />
    <xsl:for-each select="0 to $rows - 1">
        <xsl:value-of select="$nodes[(position() - 1) mod $rows = current()]"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

This is assuming there are always 3 types of nodes (and therefore 3 values per row), and that they are sorted by type and by row.

Otherwise you could use:

<xsl:template match="pi:Additional_Information">
    <xsl:for-each-group select="*" group-by="tokenize(name(), '_')[last()]">        
        <xsl:value-of select="current-group()"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each-group>
</xsl:template>

This groups the nodes by whatever comes after the last underscore in their name.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163585

In XSLT 2.0:

   <xsl:template match="pi:Additional_Information">
    <xsl:for-each-group select="*" group-by="replace(name(), '[A-Za-z_]', '')">
     <loop index="{current-grouping-key()}">
      <xsl:apply-templates select="current-group()"/>
     </loop>
    </xsl:for-each-group>
  </xsl:template>

Upvotes: 0

Related Questions