Distinct list based off values of two elements

J

johkar

I need to get distinct ID and DATE combinations and I am unsure how to
do it. I need a 1.0 solution. Getting a unique list based on one
element's value I can do, but this has me stumped so far. Below are
sample source and result XML.

Reduced source XML:

<?xml version="1.0" encoding="UTF-8"?>
<POL>
<POLFORMS>
<FORMS>
<ID>12455</ID>
<BUS_TYPE>HAT</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>
<FORMS>
<ID>12455</ID>
<BUS_TYPE>INS</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>
<FORMS>
<ID>12455</ID>
<BUS_TYPE>INS</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>
<FORMS>
<ID>12455</ID>
<BUS_TYPE>HAT</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>

<FORMS>
<ID>12456</ID>
<BUS_TYPE>INS</BUS_TYPE>
<DATE>07-2010</DATE>
</FORMS>
<FORMS>
<ID>12456</ID>
<BUS_TYPE>INS</BUS_TYPE>
<DATE>07-2010</DATE>
</FORMS>
<FORMS>
<ID>12456</ID>
<BUS_TYPE>POM</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>
<FORMS>
<ID>12456</ID>
<BUS_TYPE>POM</BUS_TYPE>
<DATE>07-2008</DATE>
</FORMS>
</POLFORMS>
</POL>

This is what I want to end up with, unique ID - DATE combo list. I
will be bringing along other nodes also, but this is the essence.

<POL>
<POLFORMS>
<FORMS>
<ID>12455</ID>
<DATE>07-2008</DATE>
</FORMS>
<FORMS>
<ID>12456</ID>
<DATE>07-2010</DATE>
</FORMS>
<FORMS>
<ID>12456</ID>
<DATE>07-2008</DATE>
</FORMS>
</POLFORMS>
</POL>
 
P

P. Lepin

johkar said:
I need to get distinct ID and DATE combinations and I am unsure how to
do it. I need a 1.0 solution. Getting a unique list based on one
element's value I can do, but this has me stumped so far. Below are
sample source and result XML.

In case your XSLT processor supports key()s in key
expressions, this can be done cleanly with a couple of
simple keys. If not, just filter explicitly on match.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="idDate" match="FORMS"
use="concat(ID, '|', DATE)"/>
<xsl:key name="uniqIdDate" match="FORMS"
use="
count(.|key('idDate', concat(ID, '|', DATE))[1])
"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="POLFORMS">
<method-1>
<xsl:apply-templates select="key('uniqIdDate', 1)"/>
</method-1>
<method-2>
<xsl:apply-templates select="FORMS"
mode="unique-id-date"/>
</method-2>
</xsl:template>
<xsl:template match="FORMS" mode="unique-id-date">
<xsl:variable name="id" select="ID"/>
<xsl:variable name="date" select="DATE"/>
<xsl:if test="
count(
preceding-sibling::FORMS[ID = $id and DATE = $date]
) = 0
">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
 
J

johkar

johkar said:
I need to get distinct ID and DATE combinations and I am unsure how to
do it.  I need a 1.0 solution.  Getting a unique list based on one
element's value I can do, but this has me stumped so far.  Below are
sample source and result XML.

In case your XSLT processor supports key()s in key
expressions, this can be done cleanly with a couple of
simple keys. If not, just filter explicitly on match.

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="idDate" match="FORMS"
    use="concat(ID, '|', DATE)"/>
  <xsl:key name="uniqIdDate" match="FORMS"
    use="
      count(.|key('idDate', concat(ID, '|', DATE))[1])
    "/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="POLFORMS">
    <method-1>
      <xsl:apply-templates select="key('uniqIdDate', 1)"/>
    </method-1>
    <method-2>
      <xsl:apply-templates select="FORMS"
        mode="unique-id-date"/>
    </method-2>
  </xsl:template>
  <xsl:template match="FORMS" mode="unique-id-date">
    <xsl:variable name="id" select="ID"/>
    <xsl:variable name="date" select="DATE"/>
    <xsl:if test="
      count(
        preceding-sibling::FORMS[ID = $id and DATE = $date]
      ) = 0
    ">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Excellent, thank you. I was making it out to be harder than it
actually was.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top