[xsl] Remove duplicates using preceding- or following-siblings

Subject: [xsl] Remove duplicates using preceding- or following-siblings
From: Satish <p.satishchandra@xxxxxxxxx>
Date: Mon, 2 Apr 2012 17:50:44 +0530
Hi,
I am working on a stylesheet to process my XML data but can't seem to
resolve duplicates successfully.
The first thing to note is that I am compiling the whole data into a
xsl:variable that I am going to refer at various places in the
stylesheet. But due to this, my preceding-sibling and
following-sibling calls do not work because probably the context is
messed up (in my brain).

I, basically, write the following XML into my xsl variable:-
<LibraryAuthor>
B <LibraryBook 1> B <!-- list of books by this author after removing
duplicates -->
B <LibraryBook 2>
</LibraryAuthor>

Here's a simplified analogy of my XML

<library>
B  <book id="Bk1" authorId="A1" name="Book1"/>
B  <book id="Bk2" authorId="A2" name="Book2"/>
B  <author id="A2" name="Auth2" />
B  <book id="Bk2" authorId="A2" name="Book2"/>
B  <author id="A1" name="Auth1"/>
B  <book id="Bk4" authorId="A1" name="Book4"/>
B  ...
</library>

Now, here's a snippet of my XSL

<xsl:variable name="authorsList">
B  <xsl:call-template name="compileAuthList"/>
</xsl:variable>

<xsl:template match="/">
B  <html>
B B B  <body>
B B B B B  <table>
B B B B B B B  <tr>
B B B B B B B B B  <td>Library Name</td>
B B B B B B B B B  ...
B B B B B B B  </tr>
B B B B B  </table>
B B B  </body>
B  </html>
</xsl:template>

<xsl:template name="compileAuthList">

B  <xsl:for-each select="author">
B B B  <LibraryAuthor>
B B B B B  <xsl:attribute name="authName">
B B B B B B B  <xsl:value-of select="@name"/>
B B B B B  </xsl:attribute>
B B B B B  ...
B B B B B  <xsl:call-template name="getBooksOfAuthor">
B B B B B B B  <xsl:with-param name="authId" select="@id"/>
B B B B B  </xsl:call-template>
B B B  </LibraryAuthor>
B  </xsl:for-each>
</xsl:template>

<xsl:template name="getBooksOfAuthor">
B  <xsl:param name="authId"/>

B  <xsl:for-each select="book[@authorId = $authId]">

B B B  <!-- Since the library can contain multiple copies of the same book,
B  B  B  B  B  I need to look for duplicates before I write this LibraryBook

B  B  B  B  B <xsl:if test="count(preceding-sibling::LibraryBook[@authId =
$authId])">

B  B  B  B  B doesn't work because we are in the XML doc's <book> node and I
B  B  B  B  B do not know how to check for previously written <LibraryBook>
nodes.
B  B  B  B  B Let's just say that I cannot run the duplicate check on the
xml data - I have
B  B  B  B  B to do it here on my <LibraryBook> nodes.
B B B B B  -->

B B B  <LibraryBook>
B B B B B  <xsl:attribute name="bookName">
B B B B B B B  <xsl:value-of select="@name"/>
B B B B B  </xsl:attribute>
B  B  B <xsl:attribute name="authId">
B  B  B  B <xsl:value-of select="@authorId"/>
B  B  B </xsl:attribute>
B B B  </LibraryBook>
B  </xsl:for-each>

</xsl:template>

Hoping for some help...

Satish

Current Thread