Reputation: 127
I would like to disply state and country names in alphabetical order. If there are any county1 node assosiated with state I need to display all states with in the counry name.however if there is no state that starts with a certain alphabet like say "X" then it shouldn't show an empty . I'm pretty sure this is possible with xslt but have no idea how to go about doing it. So you gurus out there, pleeeeeeease help me.I am using visaul stuido2010 xml editor and xslt1.0.. I have no way to change the xslt version..I got struck here..
My Input xml Looka like below :
<?xml version="1.0" encoding="utf-8" ?>
<countries>
<country>
<state>Ontario</state>
<country1>CANADA</country1>
</country>
<country>
<state>Swindon</state>
</country>
<country>
<state>CAMDEN</state>
</country>
<country>
<state>NJ</state>
<country1>America</country1>
</country>
<country>
<state>NJ</state>
<country1>America</country1>
</country>
<country>
<state>NY</state>
<country1>America</country1>
</country>
<country>
<state>DE</state>
<country1>America</country1>
</country>
<country>
<state>Queenland</state>
<country1>Australia</country1>
</country>
<country>
<state>APstate</state>
</country>
<country>
<state>ANstate</state>
</country>
</countries>
My output looks like as below :
A
America
- DE
- NJ
- NY
ANstate
APstate
Australia
-Queenland
C
CAMDEN
CANADA
-Ontario
S
Swindon
Upvotes: 0
Views: 145
Reputation: 4403
This gives you the precise output you request.
Note this is triple-level grouping, which in XSLT 1.0 is most easily done with variables instead of using the Muenchian method. It is even easier in XSLT 2.0.
t:\ftemp>type countries.xml
<?xml version="1.0" encoding="utf-8" ?>
<countries>
<country>
<state>Ontario</state>
<country1>CANADA</country1>
</country>
<country>
<state>Swindon</state>
</country>
<country>
<state>CAMDEN</state>
</country>
<country>
<state>NJ</state>
<country1>America</country1>
</country>
<country>
<state>NJ</state>
<country1>America</country1>
</country>
<country>
<state>NY</state>
<country1>America</country1>
</country>
<country>
<state>DE</state>
<country1>America</country1>
</country>
<country>
<state>Queenland</state>
<country1>Australia</country1>
</country>
<country>
<state>APstate</state>
</country>
<country>
<state>ANstate</state>
</country>
</countries>
t:\ftemp>call xslt countries.xml countries.xsl
A
America
- DE
- NJ
- NY
ANstate
APstate
Australia
- Queenland
C
CAMDEN
CANADA
- Ontario
S
Swindon
t:\ftemp>type countries.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="countries">
<!--set the population to be all top-level sorted constructs-->
<xsl:variable name="countries"
select="country/country1 | country[not(country1)]/state"/>
<xsl:for-each select="$countries">
<xsl:sort select="."/>
<xsl:if test="generate-id(.)=
generate-id($countries[substring(.,1,1) =
substring(current(),1,1)][1])">
<!--at first of the letter-->
<xsl:variable name="letters"
select="$countries[substring(.,1,1) =
substring(current(),1,1)]"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="substring(.,1,1)"/>
<xsl:for-each select="$letters">
<xsl:sort select="."/>
<xsl:if test="generate-id(.)=
generate-id($letters[. = current()][1])">
<!--at first of a country-->
<xsl:text>
</xsl:text>
<xsl:value-of select="."/>
<xsl:variable name="states"
select="$letters[. = current()]
[self::country1]/../state"/>
<xsl:for-each select="$states">
<xsl:sort select="."/>
<xsl:if test="generate-id(.)=
generate-id($states[.=current()][1])">
<!--each of the states for a country-->
<xsl:text>
 - </xsl:text>
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>rem Done!
Upvotes: 0