Pieter_mov
Pieter_mov

Reputation: 15

XSLT 1.0 get distinct with multiple child nodes

I have an xml with multiple nodes and subnodes. And I need the distinct nodes. I've found a lot of examples, but they are for single child nodes, not when I want to check on multiple child nodes. They either don't work for me, or I only get 1 subnode every time. Not the full Row group.

<Rowsets>
  <Rowset>
    <Row>
       <alpha>1111</alpha>
       <bravo>2222</bravo>
       <charlie>3333</charlie>
    </Row>
    <Row>
       <alpha>165165</alpha>
       <bravo>2165165</bravo>
       <charlie>654165</charlie>
    </Row>
    <Row>
       <alpha>1111</alpha>
       <bravo>2222</bravo>
       <charlie>3333</charlie>
    </Row>
  </Rowset>
</Rowsets>

So I need an output with distinct Row nodes. As you can see, the first and last Row node are the same. How do I get an output with only 2 Row nodes, since the 3rd is only a double.

Something like this:

<Rowsets>
  <Rowset>
    <Row>
       <alpha>1111</alpha>
       <bravo>2222</bravo>
       <charlie>3333</charlie>
    </Row>
    <Row>
       <alpha>165165</alpha>
       <bravo>2165165</bravo>
       <charlie>654165</charlie>
    </Row>
  </Rowset>
</Rowsets>

Rowsets node is not necessary. I just need the unique Row nodes.

Currently I'm trying to find it in this direction:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
     <xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Rowsets/Rowset/Row[alpha = following::Rowsets/Rowset/Row/alpha and bravo = following::Rowsets/Rowset/Row/bravo and charlie = following::Rowsets/Rowset/Row/charlie]"/>  
</xsl:stylesheet>

Upvotes: 1

Views: 900

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117165

Use Muenchian grouping. Make your key:

<xsl:key name="row" match="Row" use="concat(alpha, '|', bravo, '|', charlie)" />

and output only Rows that satisfy:

Row[count(. | key('row', concat(alpha, '|', bravo, '|', charlie))[1]) = 1]

Upvotes: 2

Rupesh_Kr
Rupesh_Kr

Reputation: 3445

try this

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="Row[. = preceding-sibling::Row]"/>  

Upvotes: -1

Related Questions