XSLT: delete duplicates + set sequence

Advertisements

I need to delete duplicates from xml + set correct sequence i.e. 10, 20, 30 etc.

My xml:

<?xml version="1.0" encoding="UTF-8"?>

<serviceInvocationRequests>
  <serviceInvocationRequest>
    <requests>
      <workCenter>04901</workCenter>
      <description>Some random description</description>
    <resourceMemberList>
        <resource>R4902A01</resource>
        <sequence>10</sequence>
      </resourceMemberList>
            <resourceMemberList>
        <resource>R4902A02</resource>
        <sequence>10</sequence>
      </resourceMemberList>
            <resourceMemberList>
        <resource>R4902A01</resource>
        <sequence>10</sequence>
      </resourceMemberList>
            <resourceMemberList>
        <resource>R4902A02</resource>
        <sequence>10</sequence>
      </resourceMemberList>
        </requests>
  </serviceInvocationRequest>
</serviceInvocationRequests>

My xslt for deleting duplicates:
(currently works on 1 value (common:resource) but probably I will need more – thats why concat added)

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml"/>
    <xsl:strip-space elements="*"/>

    <xsl:key match="resourceMemberList" name="group-key" use="concat(resource, '|')"/>

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="resourceMemberList[generate-id() = generate-id(key('group-key', concat(resource, '|'))[1])]">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="resourceMemberList"/>

</xsl:stylesheet>

Remove duplicates works fine, but I need to set sequence to 10 and 20

<?xml version="1.0" encoding="UTF-8"?>
<serviceInvocationRequests>
   <serviceInvocationRequest>
      <requests>
         <workCenter>04901</workCenter>
         <description>Some random description</description>
         <resourceMemberList>
            <resource>R4902A01</resource>
            <sequence>10</sequence>
         </resourceMemberList>
         <resourceMemberList>
            <resource>R4902A02</resource>
            <sequence>10</sequence>
         </resourceMemberList>
      </requests>
   </serviceInvocationRequest>
</serviceInvocationRequests>

How can I achive that?
When I try to add something to xslt duplicate logic gets broken.
Thank you!

>Solution :

I would use xsl:number:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:key match="resourceMemberList" name="group-key" use="concat(resource, '|')"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="sequence">
    <xsl:copy>
      <xsl:variable name="pos">
        <xsl:number count="resourceMemberList[generate-id() = generate-id(key('group-key', concat(resource, '|'))[1])]"/>
      </xsl:variable>
      <xsl:value-of select="10 * $pos"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="resourceMemberList[not(generate-id() = generate-id(key('group-key', concat(resource, '|'))[1]))]"/>

</xsl:stylesheet>

Leave a ReplyCancel reply