Reputation: 159
The below is the input xml that has reasoncase element which is repeating.If code under reasonCase is having the value starts with Applicant then create applicant.
<input>
<case>
<reasonCase>
<code>Applicant#1234</code>
<key>asd345</key>
</reasonCase>
<reasonCase>
<code>Applicant#1234</code>
<key>asd34567</key>
</reasonCase>
<reasonCase>
<code>Applicant#3456</code>
<key>asd1111</key>
</reasonCase>
<reasonCase>
<code>Applicant#7889</code>
<key>asd9999</key>
</reasonCase>
</case>
</input>
Expected output is code under reasonCase with same value should be in same applicant element in the output and corresponding elements also should be in the same applicant element
<output>
<case>
<applicant>
<objectid>1234</objectid>
<reason>
<key>asd345</key>
</reason>
<reason>
<key>asd34567</key>
</reason>
</applicant>
<applicant>
<objectid>3456</objectid>
<reason>
<key>asd1111</key>
</reason>
</applicant>
<applicant>
<objectid>7889</objectid>
<reason>
<key>asd9999</key>
</reason>
</applicant>
</case>
</output>
Based on the reasonCase/code = start-with(Applicant) have to create the repeated elements applicant and corresponding elements.
Please find the below xslt that I tried
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<output>
<xsl:for-each select="/input/case/reasonCase">
<xsl:variable name="code">
<xsl:value-of select="./code"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="starts-with(./code,'Applicant')">
<Applicants>
<objectId>
<xsl:value-of select="substring-after(/*/*/*[code=$code]/code,'Applicant#')"/>
</objectId>
<reason>
<key><xsl:value-of select="/*/*/*[code=$code]/key"/></key>
</reason>
</Applicants>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
The output that I got is as below
<output>
<Applicants>
<objectId>1234</objectId>
<reason>
<key>asd345</key>
</reason>
</Applicants>
<Applicants>
<objectId>1234</objectId>
<reason>
<key>asd345</key>
</reason>
</Applicants>
<Applicants>
<objectId>3456</objectId>
<reason>
<key>asd1111</key>
</reason>
</Applicants>
<Applicants>
<objectId>7889</objectId>
<reason>
<key>asd9999</key>
</reason>
</Applicants>
</output>
Please help me in order to get the expected output.
Upvotes: 0
Views: 893
Reputation: 3445
For Xsl 1.0 you can use
<xsl:template match="input">
<output>
<case>
<xsl:for-each select="//code[.!=preceding::code or not(preceding::code)]">
<xsl:variable name="code" select="text()"/>
<Applicants>
<objectid><xsl:value-of select="substring-after(text(), '#')"/></objectid>
<xsl:for-each select="//key[preceding-sibling::code = $code]">
<reason>
<xsl:copy-of select="."/>
</reason>
</xsl:for-each>
</Applicants>
</xsl:for-each>
</case>
</output>
and output for this is
<?xml version="1.0" encoding="UTF-8"?>
<output>
<case>
<Applicants>
<objectid>1234</objectid>
<reason>
<key>asd345</key>
</reason>
<reason>
<key>asd34567</key>
</reason>
</Applicants>
<Applicants>
<objectid>3456</objectid>
<reason>
<key>asd1111</key>
</reason>
</Applicants>
<Applicants>
<objectid>7889</objectid>
<reason>
<key>asd9999</key>
</reason>
</Applicants>
</case>
</output>
Upvotes: 1
Reputation: 3445
xslt for this issue
<xsl:template match="input">
<output>
<case>
<xsl:for-each-group select="//code" group-by="text()">
<xsl:variable name="code" select="text()"/>
<applicant>
<objectid><xsl:value-of select="substring-after(text(), '#')"/></objectid>
<xsl:for-each select="//key[preceding-sibling::code = $code]">
<reason>
<xsl:copy-of select="."/>
</reason>
</xsl:for-each>
</applicant>
</xsl:for-each-group>
</case>
</output>
</xsl:template>
and output
<?xml version="1.0" encoding="UTF-8"?>
<output>
<case>
<applicant>
<objectid>1234</objectid>
<reason>
<key>asd345</key>
</reason>
<reason>
<key>asd34567</key>
</reason>
</applicant>
<applicant>
<objectid>3456</objectid>
<reason>
<key>asd1111</key>
</reason>
</applicant>
<applicant>
<objectid>7889</objectid>
<reason>
<key>asd9999</key>
</reason>
</applicant>
</case>
</output>
Upvotes: 0