Home > database >  Remove/Avoid duplicates from combined list of items
Remove/Avoid duplicates from combined list of items

Time:03-18

I have an exsl:node-set with an array of items that I used as a lookup table to display the Location of from another unique list that I have built from the XML document itself. The lookup works fine, however, I would like to be able to remove duplicates form the resulting data set.

The following image illustrates the problem.

enter image description here

XML Document

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="default.xsl"?>
<TestResults>
    <Result>
        <TestID>1001</TestID>
        <ResultValue>2.5</ResultValue>
        <InstrumentID>503||1</InstrumentID>
    </Result>
    <Result>
        <TestID>1002</TestID>
        <ResultValue>6.3</ResultValue>
        <InstrumentID>503||1</InstrumentID>
    </Result>
    <Result>
        <TestID>1003</TestID>
        <ResultValue>11</ResultValue>
        <InstrumentID>342||1</InstrumentID>
    </Result>
    <Result>
        <TestID>1004</TestID>
        <ResultValue>201</ResultValue>
        <InstrumentID>342||1</InstrumentID>
    </Result>
    <Result>
        <TestID>1005</TestID>
        <ResultValue>85</ResultValue>
        <InstrumentID>731||1</InstrumentID>
    </Result>
    <Result>
        <TestID>1006</TestID>
        <ResultValue>33.6</ResultValue>
        <InstrumentID>334||1</InstrumentID>
    </Result>
  </TestResults>

XLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:java="http://xml.apache.org/xslt/java"
    xmlns:svg="http://www.w3.org/2000/svg">

    <!-- INSTRUMENTS PER SITE ARRAY -->
    <xsl:variable name="instruments-site">
        <instrument ID='334||3'>Laboratory 1</instrument>
        <instrument ID='342||1'>Laboratory 1</instrument>
        <instrument ID='342||2'>Laboratory 1</instrument>
        <instrument ID='503||1'>Laboratory 1</instrument>
        <instrument ID='503||2'>Laboratory 1</instrument>
        <instrument ID='503||3'>Laboratory 2</instrument>
        <instrument ID='503||4'>Laboratory 2</instrument>
        <instrument ID='731||1'>Laboratory 2</instrument>
    </xsl:variable>
    <xsl:variable name="list-instruments-site" select="exsl:node-set($instruments-site)" xmlns:exsl="http://exslt.org/common"/>

    <!-- INSTRUMENT LIST-->
    <xsl:key name="key-instruments" match="/TestResults/Result" use="InstrumentID"/>
    <xsl:key name="key-instruments-list" match="/TestResults/Result/InstrumentID" use="."/>
    <xsl:variable name="unique-instruments-list" select="//TestResults/Result/InstrumentID[generate-id() = generate-id(key('key-instruments-list', .)[1])]"/> 
    
    <xsl:variable name="unique-location-list" select="$list-instruments-site/instrument[generate-id() = generate-id(key('key-instruments-list', .)[1])]"/> 

    <xsl:template match="/TestResults">
        <html>
            <head>
                <title>Test Document</title>
            </head>
            <body>     
                <h2>Instruments</h2>
                <xsl:apply-templates select="$unique-instruments-list" mode="instr-locations" />
            </body>
        </html>
    </xsl:template>

    <xsl:template mode="instr-locations" match="text()">
        <xsl:value-of select="." />
        <br/>
    </xsl:template>
</xsl:stylesheet>

What I have tried

  1. I tried building a third unique list from using the $unique-location-list like this:
    <xsl:variable name="unique-location-list" select="$list-instruments-site/instrument[generate-id() = generate-id(key('key-instruments-list', .)[1])]"/> 
  1. I have also tried using preceding-sibling on the instr-locations template, like this:
<xsl:variable name="previous" select="preceding-sibling::$list-instruments-site/instrument" />
<xsl:if test="$previous != current()">
  <xsl:value-of select="$list-instruments-site/instrument[@ID=current()]" />
</xsl:if>

I appreciate the help in advance. Keep in mind that the solution has to be in XSLT 1.0.

Desired HTML output

I expect something similar to this as HTML output, answering @martinhonnen's comment.

<ul>
 <li>Laboratorio 1</li>
 <li>Laboratorio 2</li>
</ul>

CodePudding user response:

Would you be able to do something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xsl:variable name="labs">
    <lab name="Laboratory 1">
        <instrument ID="334||3"/>
        <instrument ID="342||1"/>
        <instrument ID="342||2"/>
        <instrument ID="503||1"/>
        <instrument ID="503||2"/>
     </lab>
    <lab name="Laboratory 2">
        <instrument ID="503||3"/>
        <instrument ID="503||4"/>
        <instrument ID="731||1"/>
    </lab>
</xsl:variable>
    
<xsl:template match="/TestResults">
    <xsl:variable name="instrumentIDs" select="Result/InstrumentID" />
    <html>
        <body>
            <xsl:for-each select="exsl:node-set($labs)/lab[instrument/@ID = $instrumentIDs]">
                <xsl:value-of select="@name" /><br/>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>
  • Related