Reputation: 53
I have requirement to combine 2 xml file into single file with distinct child node in result file. I am able to combine file based on key node but child element value is not coming properly.
Please find below detail.
XML file 1-
<?xml version="1.0" encoding="UTF-8"?>
<EF_Candidate_List>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<name>test</name>
<preflocation>USA</preflocation>
</EF_Candidate>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<name>test</name>
<preflocation>IND</preflocation>
</EF_Candidate>
</EF_Candidate_List>
XML file 2-
<EF_Candidate_list>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<JobLevel>1</JobLevel>
<jobtype>test1</jobtype>
<job_shedule>day</job_shedule>
</EF_Candidate>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<JobLevel>2</JobLevel>
<jobtype>test2</jobtype>
<job_shedule>day</job_shedule>
</EF_Candidate>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<JobLevel>2</JobLevel>
<jobtype>test2</jobtype>
<job_shedule>Night</job_shedule>
</EF_Candidate>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<JobLevel>3</JobLevel>
<jobtype>test3</jobtype>
<job_shedule>Night</job_shedule>
</EF_Candidate>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<JobLevel>3</JobLevel>
<jobtype>test3</jobtype>
<job_shedule>Night</job_shedule>
</EF_Candidate>
</EF_Candidate_list>
Expected result file
<EF_Candidate_List>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<name>test</name>
<preflocation_list>
<preflocation>IND</preflocation>
<preflocation>USA</preflocation>
<preflocation_list>
<profiles>
<profile>
<JobLevel>1</JobLevel>
<jobtype>test1</jobtype>
</profile>
<profile>
<JobLevel>2</JobLevel>
<jobtype>test2</jobtype>
</profile>
<profile>
<JobLevel>3</JobLevel>
<jobtype>test3</jobtype>
</profile>
</profiles>
<jobshedule_list>
<job_shedule>day</job_shedule>
<job_shedule>Night</job_shedule>
</jobshedule_list>
</EF_Candidate_List>
</EF_Candidate>
I have following code
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="EF_Candidate_List">
<EF_Candidate_List xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:for-each-group select="EF_Candidate" group-by="candidate_id">
<EF_Candidate>
<xsl:variable name="current_candidate_id" select="candidate_id"/>
<xsl:variable name="JobLevel" select="document('file2.xml')/EF_Candidate_List/EF_Candidate[candidate_id = $current_candidate_id]/JobLevel" />
<xsl:sequence select="candidate_id" />
<name><xsl:value-of select="name"/></name>
<preflocation_list>
<xsl:for-each-group select="current-group()" group-by="preflocation">
<preflocation><xsl:value-of select="distinct-values(.)"/></preflocation>
</xsl:for-each-group>
<preflocation_list>
<JobLevel_list>
<xsl:for-each-group select="document('file2.xml')/EF_Candidate_List/EF_Candidate[candidate_id = $current_candidate_id]/JobLevel" group-by="$JobLevel">
<JobLevel><xsl:value-of select="distinct-values(.)"/></JobLevel>
</xsl:for-each-group>
</JobLevel_list>
</EF_Candidate>
</xsl:for-each-group>
</EF_Candidate_List>
</xsl:template>
current output
<EF_Candidate_List>
<EF_Candidate>
<candidate_id>83185</candidate_id>
<name>test</name>
<preflocation_list>
<preflocation>IND</preflocation>
<preflocation>USA</preflocation>
<preflocation_list>
<JobLevels>
<JobLevel>1</JobLevel>
<JobLevel>1</JobLevel>
<JobLevel>1</JobLevel>
</JobLevels>
</EF_Candidate_List>
</EF_Candidate>
I am new to xslt hence finding difficulties to trouble shoot. Any help will be much appreciated.
Upvotes: 0
Views: 36
Reputation: 117140
I believe this does what you asked for:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="cnd" match="EF_Candidate" use="candidate_id" />
<xsl:template match="/EF_Candidate_List">
<xsl:copy>
<xsl:for-each-group select="EF_Candidate" group-by="candidate_id">
<xsl:copy>
<!-- data from input file -->
<xsl:copy-of select="candidate_id, name"/>
<preflocation_list>
<xsl:copy-of select="current-group()/preflocation"/>
</preflocation_list>
<!-- data from other file -->
<xsl:variable name="profiles" select="key('cnd', candidate_id, document('file2.xml'))" />
<profiles>
<xsl:for-each-group select="$profiles" group-by="JobLevel">
<profile>
<xsl:copy-of select="JobLevel, jobtype"/>
</profile>
</xsl:for-each-group>
</profiles>
<jobshedule_list>
<xsl:for-each-group select="$profiles" group-by="job_shedule">
<xsl:copy-of select="job_shedule"/>
</xsl:for-each-group>
</jobshedule_list>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1