Murali
Murali

Reputation: 148

XSLT Transformation of multiple tags into single tag

I want to create an XSLT to transform this below XML... e.g., Each person will have 2 JobInfo tags in sequence followed by 2 EmpInfo. I want to merge the 1st JobInfo with 1st EmpInfo and the 2nd JobInfo with 2nd EmpInfo. and transform them as EmpJobInfo.

 <soap:Envelope xmlns:soap="schemas.xmlsoap.org/soap/envelope/">
 <soap:Body> 
 <App> 
 <person>
 <answerSet>
    <answers>
        <entry>
            <key>monthlyIncome</key>
            <value>1200</value>
        </entry>
    </answers>
    <key>JobInfo</key>
 </answerSet>
 <answerSet>
    <answers>
        <entry>
            <key>monthlyIncome</key>
            <value>800</value>
        </entry>
    </answers>
    <key>JobInfo</key>
</answerSet>
<answerSet>
    <answers>
        <entry>
            <key>EmpName</key>
            <value>Walmart</value>
        </entry>
    </answers>
    <key>EmpInfo</key>
</answerSet>
<answerSet>
    <answers>
        <entry>
            <key>EmpName</key>
            <value>Target</value>
        </entry>
    </answers>
    <key>EmpInfo</key>
</answerSet>
</person>
</App> 
</soap:Body> 
</soap:Envelope>

to have the result as

<answerSet>
    <answers>
        <entry>
            <key>EmpName</key>
            <value>Walmart</value>
        </entry>
    </answers>
    <answers>
        <entry>
            <key>monthlyIncome</key>
            <value>1200</value>
        </entry>
    </answers>
    <key>EmpJobInfo</key>
</answerSet>
<answerSet>
    <answers>
        <entry>
            <key>EmpName</key>
            <value>Target</value>
        </entry>
    </answers>
    <answers>
        <entry>
            <key>monthlyIncome</key>
            <value>800</value>
        </entry>
    </answers>
    <key>EmpJobInfo</key>
</answerSet>

Upvotes: 0

Views: 874

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117165

Each person will have 2 JobInfo tags in sequence followed by 2 EmpInfo. I want to merge the 1st JobInfo with 1st EmpInfo and the 2nd JobInfo with 2nd EmpInfo. and transform them as EmpJobInfo.

You could it this way:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="soap">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/soap:Envelope">
    <root>
        <xsl:apply-templates select="soap:Body/App/person"/>
    </root>
</xsl:template>

<xsl:template match="person">
    <xsl:variable name="JobInfo" select="answerSet[key='JobInfo']/answers" />
    <xsl:variable name="EmpInfo" select="answerSet[key='EmpInfo']/answers" />
    <answerSet>
        <xsl:apply-templates select="$EmpInfo[1]"/>
        <xsl:apply-templates select="$JobInfo[1]"/>
        <key>EmpJobInfo</key>
    </answerSet>
    <answerSet>
        <xsl:apply-templates select="$EmpInfo[2]"/>
        <xsl:apply-templates select="$JobInfo[2]"/>
        <key>EmpJobInfo</key>
    </answerSet>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Note the added root element on the output.

Upvotes: 0

Mike
Mike

Reputation: 1091

Assuming the answerSet nodes always appear in groups of 4 per person node as in the example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="*">
    <App>
      <xsl:for-each select="//person">
        <xsl:variable name ="person" select="." />
        <person>
          <xsl:for-each select="answerSet[key='EmpInfo']">
            <xsl:variable name ="pos" select="position()" />
            <answerSet>
              <xsl:copy-of select="answers" />
              <xsl:copy-of select="$person/answerSet[key='JobInfo'][$pos]/answers" />
              <key>EmpJobInfo</key>
            </answerSet>
          </xsl:for-each>
        </person>
      </xsl:for-each>
    </App>
  </xsl:template>
</xsl:stylesheet>

Provides this output:

<App>
  <person>
    <answerSet>
      <answers>
        <entry>
          <key>EmpName</key>
          <value>Walmart</value>
        </entry>
      </answers>
      <answers>
        <entry>
          <key>monthlyIncome</key>
          <value>1200</value>
        </entry>
      </answers>
      <key>EmpJobInfo</key>
    </answerSet>
    <answerSet>
      <answers>
        <entry>
          <key>EmpName</key>
          <value>Target</value>
        </entry>
      </answers>
      <answers>
        <entry>
          <key>monthlyIncome</key>
          <value>800</value>
        </entry>
      </answers>
      <key>EmpJobInfo</key>
    </answerSet>
  </person>
</App>

Upvotes: 1

Related Questions