Comparing 2 consecutive Rows of XML using XSLT -


hi trying compare 2 consecutive entries following xml.

<wd:report_data xmlns:wd="urn:com.workday.report/test">             <wd:report_entry>                 <wd:location_changes>                     <wd:employeeid>111111</wd:employeeid>                     <wd:countrycode>us</wd:countrycode>                     <wd:regioncode>rx</wd:regioncode>                     <wd:startdate>2013-07-01</wd:startdate>                 </wd:location_changes>                 <wd:location_changes>                     <wd:employeeid>111111</wd:employeeid>                     <wd:countrycode>us</wd:countrycode>                     <wd:regioncode>md</wd:regioncode>                     <wd:startdate>2009-09-14</wd:startdate>                 </wd:location_changes>                 <wd:location_changes>                     <wd:employeeid>111111</wd:employeeid>                     <wd:countrycode>us</wd:countrycode>                     <wd:regioncode>md</wd:regioncode>                     <wd:startdate>2009-10-14</wd:startdate>                 </wd:location_changes>                 <wd:location_changes>                     <wd:employeeid>111111</wd:employeeid>                     <wd:countrycode>us</wd:countrycode>                     <wd:regioncode>rx</wd:regioncode>                     <wd:startdate>2014-07-01</wd:startdate>                 </wd:location_changes>             </wd:report_entry>         </wd:report_data> 

the output is:

    employeeid|countrycode|regioncode|startdate         "111111"|"us"|"rx"|"2014-07-01"         "111111"|"us"|"md"|"2009-10-14"         "111111"|"us"|"md"|"2009-09-14"         "111111"|"us"|"rx"|"2013-07-01"" 

but expecting:

    employeeid|countrycode|regioncode|startdate         "111111"|"us"|"rx"|"2014-07-01"         "111111"|"us"|"md"|"2009-10-14"         "111111"|"us"|"rx"|"2013-07-01" 

if there consecutive entry same combination "employeeid|regioncode", entry should not included. have used primary key make sure there no duplicate entry.

i using following xslt:

<?xml version="1.0" encoding="utf-8"?>     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"                     xmlns:xs="http://www.w3.org/2001/xmlschema"                     xmlns:wd="urn:com.workday.report/test"                     exclude-result-prefixes="xs"                     version="2.0">         <xsl:output method="text"                     omit-xml-declaration="yes"/>         <!-- variables hold fillers - pipe, new line, double quotes -->         <xsl:variable name="delimiter"                       select="'|'"/>         <xsl:variable name="linefeed"                       select="'&#xd;&#xa;'"/>         <xsl:variable name="dquote">"</xsl:variable>         <xsl:variable name="duplicate_key"                  match="wd:report_data/wd:report_entry/wd:location_changes"                  select="concat(wd:employeeid,'|',wd:regioncode)" />         <!--to remove duplicates-->         <xsl:key name="primary_key"                  match="wd:report_data/wd:report_entry/wd:location_changes"          use="concat(wd:employeeid,'|',wd:regioncode,'|',wd:startdate)" />         <xsl:template match="/">             <!-- header row begin -->             <xsl:text>employeeid</xsl:text>             <xsl:value-of select="$delimiter"/>             <xsl:text>countrycode</xsl:text>             <xsl:value-of select="$delimiter"/>             <xsl:text>regioncode</xsl:text>             <xsl:value-of select="$delimiter"/>             <xsl:text>startdate</xsl:text>             <xsl:value-of select="$linefeed"/>             <!-- header row end -->             <!-- data row starts -->             <!-- parse each , every employee record -->                    <!--to reverse records , remove duplicates-->             <xsl:for-each select="wd:report_data/wd:report_entry/wd:location_changes[generate-id()= generate-id(key('primary_key',concat(wd:employeeid,'|',wd:regioncode,'|',wd:startdate))[1])]">                 <xsl:sort select="position()"                           data-type="number"                           order="descending"/>                   <xsl:call-template name="output">                     <xsl:with-param name="unique_code"/>                                 </xsl:call-template>             </xsl:for-each>         </xsl:template>         <xsl:template name="output">             <xsl:param name="unique_code"/>             <!-- data row begins -->             <xsl:if test="$duplicate_key != concat(wd:employeeid,'|',wd:regioncode)">                 <!-- #1 employeeid -->                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="wd:employeeid"/>                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="$delimiter"/>                 <!-- #2 countrycode -->                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="wd:countrycode"/>                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="$delimiter"/>                 <!-- #3 regioncode-->                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="wd:regioncode"/>                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="$delimiter"/>                 <!-- #4 startdate-->                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="wd:startdate"/>                 <xsl:value-of select="$dquote"/>                 <xsl:value-of select="$linefeed"/>               </xsl:if>                    <!-- remove consecutive duplicates-->             <xsl:variable name="duplicate_key"?                  match="wd:report_data/wd:report_entry/wd:location_changes"                  select="concat(wd:employeeid,'|',wd:regioncode)" />                 <!-- data row end -->         </xsl:template>     </xsl:stylesheet> 

the issue here not able remove consecutive duplicate

if there consecutive entry same combination "employeeid|regioncode", entry should not included.

unless i'm missing should able simplify process grouping adjacent wd:report_entry (based on wd:employeeid , wd:regioncode) , processing last entry in group.

note: adjacent means "next to", unlike describe in comment "only consecutive duplicates need removed , adjacent duplicates need kept.".

xml input

<wd:report_data xmlns:wd="urn:com.workday.report/test">     <wd:report_entry>         <wd:location_changes>             <wd:employeeid>111111</wd:employeeid>             <wd:countrycode>us</wd:countrycode>             <wd:regioncode>rx</wd:regioncode>             <wd:startdate>2013-07-01</wd:startdate>         </wd:location_changes>         <wd:location_changes>             <wd:employeeid>111111</wd:employeeid>             <wd:countrycode>us</wd:countrycode>             <wd:regioncode>md</wd:regioncode>             <wd:startdate>2009-09-14</wd:startdate>             <!--remove-->         </wd:location_changes>         <wd:location_changes>             <wd:employeeid>111111</wd:employeeid>             <wd:countrycode>us</wd:countrycode>             <wd:regioncode>md</wd:regioncode>             <wd:startdate>2009-10-14</wd:startdate>             <!--keep-->         </wd:location_changes>         <wd:location_changes>             <wd:employeeid>111111</wd:employeeid>             <wd:countrycode>us</wd:countrycode>             <wd:regioncode>rx</wd:regioncode>             <wd:startdate>2014-07-01</wd:startdate>         </wd:location_changes>     </wd:report_entry> </wd:report_data> 

xslt 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"    xpath-default-namespace="urn:com.workday.report/test">   <xsl:output method="text"/>   <xsl:strip-space elements="*"/>    <xsl:template match="/*">     <xsl:text>employeeid|countrycode|regioncode|startdate&#xa;</xsl:text>     <xsl:for-each-group select="report_entry/location_changes"        group-adjacent="concat(employeeid,'|',regioncode)">       <xsl:sort select="position()" order="descending"/>       <xsl:apply-templates select="current-group()[last()]"/>     </xsl:for-each-group>   </xsl:template>    <xsl:template match="location_changes">     <xsl:value-of select="concat('&quot;',       string-join((employeeid,countrycode,regioncode,startdate),'&quot;|&quot;'),       '&quot;&#xa;')"/>   </xsl:template>  </xsl:stylesheet> 

output

employeeid|countrycode|regioncode|startdate "111111"|"us"|"rx"|"2014-07-01" "111111"|"us"|"md"|"2009-10-14" "111111"|"us"|"rx"|"2013-07-01" 

Comments

Popular posts from this blog

javascript - Clear button on addentry page doesn't work -

c# - Selenium Authentication Popup preventing driver close or quit -

tensorflow when input_data MNIST_data , zlib.error: Error -3 while decompressing: invalid block type -