This is a snippet from the xml:
<sample>
<test>
<Cell1>John</Cell1>
<Cell2>A</Cell2>
<Cell4>xy</Cell4>
</test>
<test>
<Cell1>Jack</Cell1>
<Cell2>B</Cell2>
<Cell3>Red</Cell3>
<Cell6>10</Cell6>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A,Y</Cell2>
<Cell4>1</Cell4>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A B,X</Cell2>
<Cell3>Blue</Cell3>
</test>
</sample>
If Cell2
contains comma split the values and check if the preceding Cell2
contains the same value and similarly if Cell2
contains space split the values and check if the preceding Cell2
contains the same value -> If so ignore it.
This is how I want the output:
<Cell2>A</Cell2>
<Cell2>B</Cell2>
<Cell2>Y</Cell2>
<Cell2>X</Cell2>
This is the xslt which I wrote: (please look into the comment)
<xsl:template match="sample">
<xsl:for-each select="test">
<xsl:choose>
<xsl:when test="contains(Cell2,',')">
<xsl:variable name="token1Cell2" select="tokenize(Cell2,',')"/>
<xsl:for-each select="$token1Cell2">
<xsl:choose>
<xsl:when test="contains(.,' ')">
<xsl:variable name="token2Cell2" select="tokenize(.,' ')"/>
<xsl:for-each select="$token2Cell2">
<!-- I tried to check if the preceding sibling element test/Cell2 contains the text that is not equal to the current text. But I know what I am doing is wrong as I am inside for-each tokenize. How to get the preceding-sibling? -->
<xsl:if test="preceding-sibling::test/
Cell2/text() != '.'">
<Cell2>
<xsl:value-of select="."/>
</Cell2>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:if test="preceding-sibling::test/Cell2/text() != '.'">
<Cell2>
<xsl:value-of select="."/>
</Cell2>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<Cell2>
<xsl:value-of select="Cell2"/>
</Cell2>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
How Can I acheive the output? Any Ideas??
Just this simple transformation:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="distinct-values(/*/test/Cell2/tokenize(.,'[ ,]'))">
<Cell2><xsl:value-of select="."/></Cell2>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<sample>
<test>
<Cell1>John</Cell1>
<Cell2>A</Cell2>
<Cell4>xy</Cell4>
</test>
<test>
<Cell1>Jack</Cell1>
<Cell2>B</Cell2>
<Cell3>Red</Cell3>
<Cell6>10</Cell6>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A,Y</Cell2>
<Cell4>1</Cell4>
</test>
<test>
<Cell1>John,Jade</Cell1>
<Cell2>A B,X</Cell2>
<Cell3>Blue</Cell3>
</test>
</sample>
produces the wanted, correct result:
<Cell2>A</Cell2>
<Cell2>B</Cell2>
<Cell2>Y</Cell2>
<Cell2>X</Cell2>
Explanation:
The XPath expression in the select
attribute of xsl:for-each
is the key to understand:
distinct-values(/*/test/Cell2/tokenize(.,'[ ,]'))
This produces the distinct values of the sequence of all tokenized (string values of) /*/test/Cell2