Reputation: 148
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
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
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