Home > Software design >  How can I split data and store in Multiple Nodes in XSLT
How can I split data and store in Multiple Nodes in XSLT

Time:10-28

I have following xml data:

<?xml?> 
<data>
    <first>1,2,3,4</first>
    <second>A,B,C,D</second>
</data>

How to convert it into something like this using XSLT

<result>
    <first>1</first>
    <second>A</second>
</result>
<result>
    <first>2</first>
    <second>B</second>
</result>
<result>
    <first>3</first>
    <second>C</second>
</result>
<result>
    <first>4</first>
    <second>D</second>
</result>

Is there any solution? Kindly help, please.

CodePudding user response:

An XSLT-2.0 solution can be

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
    <xsl:template match="/data">
        <xsl:variable name="first"  select="tokenize(first,',')" />
        <xsl:variable name="second" select="tokenize(second,',')" />
        <data>
            <xsl:for-each select="$first">
                <xsl:variable name="cur" select="position()" />
                <first><xsl:value-of select="." /></first>
                <second><xsl:value-of select="$second[$cur]" /></second>
            </xsl:for-each>
        </data>
    </xsl:template>
   
</xsl:stylesheet>

And its output is

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <first>1</first>
    <second>A</second>
    <first>2</first>
    <second>B</second>
    <first>3</first>
    <second>C</second>
    <first>4</first>
    <second>D</second>
</data>

And XSLT-1.0 solution would be more complicated - requiring a recursive template to dissect the comma-delimited strings.

CodePudding user response:

Here's an XSLT 3.0 solution:

<xsl:function name="f:process-pair">
  <xsl:param name="x"/>
  <xsl:param name="y"/>
  <result>
     <first>{$x}</first>
     <second>{$y}</second>
  </result>
</xsl:function>

<xsl:template match="data">
  <xsl:sequence select="for-each-pair(
               tokenize(first, ','), 
               tokenize(second, ','), 
               f:process-pair#2)"/>
</xsl:template>
  • Related