Ok, I will try to be as clear as possible
There is my XML:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<List>
</ListItem>
<Item>
<City><![CDATA[Antony]]></City>
<FirstName><![CDATA[John]]></FirstName>
<LastName><![CDATA[Smith]]></LastName>
<Age><![CDATA[35]]></Age>
</Item>
<Item>
<City><![CDATA[Paris]]></City>
<FirstName><![CDATA[Carl]]></FirstName>
<LastName><![CDATA[Black]]></LastName>
<Age><![CDATA[30]]></Age>
</Item>
<Item>
<City><![CDATA[Paris]]></City>
<FirstName><![CDATA[Mark]]></FirstName>
<LastName><![CDATA[Smith]]></LastName>
<Age><![CDATA[35]]></Age>
</Item>
<Item>
<City><![CDATA[Antony]]></City>
<FirstName><![CDATA[Joe]]></FirstName>
<LastName><![CDATA[Brown]]></LastName>
<Age><![CDATA[25]]></Age>
</Item>
</ListItem>
</List>
Now there is my xslt:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="sortKeys" select="'LastName~~City~~Age~~'" />
<xsl:param name="parentSortKeys" select="''" />
<xsl:param name="parentSortValues" select="''" />
<xsl:template match="/">
<xsl:variable name="levelKey" select="substring-before($sortKeys, '~~')"/>
<xsl:choose>
<xsl:when test="$parentSortKeys != ''">
<xsl:call-template name="TREEVIEWAPPLYFILTER">
<xsl:with-param name="levelKey" select="$levelKey"/>
<xsl:with-param name="parentSortKeys" select="$parentSortKeys"/>
<xsl:with-param name="parentSortValues" select="$parentSortValues"/>
<xsl:with-param name="builtSortKeys" select="$sortKeys"/>
<xsl:with-param name="items" select="//Item"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="TREEVIEWBUILDRESULTS">
<xsl:with-param name="items" select="//Item"/>
<xsl:with-param name="builtSortKeys" select="$sortKeys"/>
<xsl:with-param name="levelKey" select="$levelKey"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="TREEVIEWAPPLYFILTER">
<xsl:param name="items"/>
<xsl:param name="levelKey"/>
<xsl:param name="parentSortKeys"/>
<xsl:param name="parentSortValues"/>
<xsl:param name="builtSortKeys"/>
<xsl:param name="results"/>
<xsl:variable name="key" select="substring-before($parentSortKeys, '~~')"/>
<xsl:variable name="value" select="substring-before($parentSortValues, '~~')"/>
<xsl:choose>
<xsl:when test="$key != '' and $key != $levelKey">
<xsl:call-template name="TREEVIEWAPPLYFILTER">
<xsl:with-param name="items" select="$items[child::*[name() = $key and text() = $value]]"/>
<xsl:with-param name="results" select="$items[child::*[name() = $key and text() = $value]]"/>
<xsl:with-param name="parentSortKeys" select="substring-after($parentSortKeys, '~~')"/>
<xsl:with-param name="parentSortValues" select="substring-after($parentSortValues, '~~')"/>
<xsl:with-param name="builtSortKeys" select="$builtSortKeys"/>
<xsl:with-param name="levelKey" select="$levelKey"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="TREEVIEWBUILDRESULTS">
<xsl:with-param name="items" select="$results"/>
<xsl:with-param name="builtSortKeys" select="$builtSortKeys"/>
<xsl:with-param name="levelKey" select="$levelKey"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="TREEVIEWBUILDRESULTS">
<xsl:param name="levelKey"/>
<xsl:param name="builtSortKeys"/>
<xsl:param name="items"/>
<br/>
<xsl:for-each select="$items">
<xsl:copy-of select="."/><br/>
</xsl:for-each>
<br/>
<xsl:copy-of select="$levelKey"/><![CDATA[:]]><br/>
<xsl:for-each select="$items[not(preceding-sibling::*/child::*[name()=$levelKey] = child::*[name()=$levelKey])]">
<xsl:copy-of select="child::*[name()=$levelKey]"/>
<![CDATA[ --> ]]>
<xsl:copy-of select="."/><br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Like that everything works perfectly. It returns only distinct LastName. With this XML, it returns this:
---> Smith
---> Black
---> Brown
But it does not pass through the TREEVIEWAPPLYFILTER template. If I have to apply a filterâ¦
To do the test you have to change the parameters from:
Code:
<xsl:param name="sortKeys" select="'LastName~~City~~Age~~'" />
<xsl:param name="parentSortKeys" select="''" />
<xsl:param name="parentSortValues" select="''" />
To:
Code:
<xsl:param name="sortKeys" select="'City~~Age~~'" />
<xsl:param name="parentSortKeys" select="'LastName~~'" />
<xsl:param name="parentSortValues" select="'Smith~~'" />
In that case, by passing through the TREEVIEWAPPLYFILTER template, the Item nodes are cleaned to keep only ones that have the last name equal to Smith. That works, in the template TREEVIEWBUILDRESULTS, I display one by one the results and I have my two recordsâ¦
Code:
<xsl:for-each select="$items">
<xsl:copy-of select="."/><br/>
</xsl:for-each>
---> Antony John Smith 35
---> Paris Mark Smith 35
The problem append when I try to get my distinct cities (in that case):
Code:
<xsl:for-each select="$items[not(preceding-sibling::*/child::*[name()=$levelKey] = child::*[name()=$levelKey])]">
I get only the first one:
---> Antony --> Antony John Smith 35
Itâs look like when I build my node the preceding-sibling does not works anymore!
I also did that test:
1- I removed in my XML the nodes that does not have Smith as LastName ( I did the filter physicly )
2- I changed the parameters like that:
Code:
<xsl:param name="sortKeys" select="'City~~Age~~'" />
<xsl:param name="parentSortKeys" select="''" />
<xsl:param name="parentSortValues" select="''" />
This time I have the same result when I display all the results:
Code:
<xsl:for-each select="$items">
<xsl:copy-of select="."/><br/>
</xsl:for-each>
and the select distinct works too and returns that result:
---> Antony --> Antony John Smith 35
---> Paris --> Paris Carl Black 30
Itâs seem to have a different behavior if I select the nodes directly from the XML or if I create the node by passing in the TREEVIEWAPPLYFILTER templateâ¦
I hope I was enough clearâ¦
Tnx for your helpâ¦
Patrick