0

I have some XML like this:

<?xml version="1.0" encoding="UTF-8"?>
<Results>
    <Build>
            <Test>
                <car value=""/>
                <car value="abc"/>
                <car value=""/>
                <car value="xyz"/>  
            </Test> 
    </Build>
    <Build>         
            <Test>
                <car value=""/>
                <car value="xyz"/>
                <car value="xyz"/>
                <car value="mno" />
            </Test>
    </Build>
    <Build>     
            <Test>
                <car  value=""/>
                <car value="xyz"/>
                <car value="xyz"/>
                <car value="mno" />
            </Test>     
    </Build>
</Results>

and I want the out for 2nd Build node element like this:

xyz
mno

I have tried many ways.kindly refer to below code. it was working perfectly for Build[1] but when i tried to run it for particularity Build[2] and Build[3], output is not as expected.

<xsl:template match="Results">
    <xsl:apply-templates select="Build[2]" />
</xsl:template>

<xsl:template match="Build">
    <html>
        <body>
            <xsl:for-each select="Test/car[not(@value = (preceding:: car/@value))]">
                <xsl:sort select="@value" />
                <xsl:if test="@value!=''">
                    <li>
                        <xsl:value-of select='@value' />
                    </li>
                </xsl:if>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>            

It gives me this output:

<html>  
<body>  
<li>mno</li>  
</body>  
</html>  

Can someone help me to resolve this issue?

zx485
  • 28,498
  • 28
  • 50
  • 59
Meenu Garg
  • 93
  • 1
  • 6

1 Answers1

1

There is already a good answer here at SO. Applied to your special situation you have at least the following two solutions:

In XSLT-2.0 you have the distinct-values function which makes this a lot easier by simply the using this for-each loop.

<xsl:for-each select="distinct-values(Test/car/@value)">
    <xsl:sort select="." />
    <xsl:if test=".!=''">
        <li>
            <xsl:value-of select='.' />
        </li>
    </xsl:if>
</xsl:for-each>

In XSLT-1.0 the following solution will work. It's a bit more complicated, but quite similar to your approach:

<xsl:template match="Build">
    <html>
        <body>
            <xsl:for-each select="Test/car[@value!='' and not(@value=preceding-sibling::car/@value)]">
                <xsl:sort select='@value' />
                <li>
                    <xsl:value-of select='@value' />
                </li>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>
zx485
  • 28,498
  • 28
  • 50
  • 59