|
next
|
Subject: Help with using not(preceding::foo) axis multiple times in a document Author: c y Date: 07 Feb 2008 12:16 PM
|
hello,
relatively new to xslt and i've got a "remove duplicates" nut i can't seem to crack. i've got a list of stores in a (unfortunately) relatively flat xml file that i need to display first by unique state, then by unique city, and then list the individual store listings. so the final display would be something like:
Alaska
Barrow
Joe's Store
Tom's Store
Juneau
Fred's Store
Jane's Store
Washington
Seattle
Ted's Store
Elsie's Store
Tacoma
Ralph's Store
i'm stuck using xslt 1.0 (again, unfortunately), and i can successfully use the "preceding" axis to first itierate through the xml and get a unique listing of states, and then a unique listing of cities. this works great, except for when there's a city with the same name in two different states. at that point, the xsl grabs the first one it comes across in the xml and ignores the second same-named city in the other state.
i understand that "preceding" starts at the top of the document, which is why it's ignoring the second same-named city, and i can't use preceding-sibling because of the way the xml is formatted (sample xml below).
so my question is: is it possible, and if so how, to iterate through the xml to first grab the unique states, and then use preceding to iterate a second time over *only that unique list* instead iterating over the entire document again. i'm thinking this is how i can get the unique cities for their respective states.
any other ideas greatly appreciated to this newbie. i've been digging high and low online for a solution and can't find something that fits my need to use preceding more than once and on a subset of previously gathered preceding nodes. that, or i'm overlooking what i need to use.
sample xml/xslt:
<Stores>
<Store>
<StoreName>Ralph's Store</StoreName>
<StoreAddress1>4575 Sand Point Way N.E.</StoreAddress1>
<StoreCity>Seattle</StoreCity>
<StoreState>WA</StoreState>
<StoreZip>98105</StoreZip>
</Store>
<Store>
<StoreName>Fred's Store</StoreName>
<StoreAddress1>4575 Point Ave N.E.</StoreAddress1>
<StoreCity>Seattle</StoreCity>
<StoreState>WA</StoreState>
<StoreZip>98115</StoreZip>
</Store>
<Store>
<StoreName>Jim's Store</StoreName>
<StoreAddress1>575 St. NW</StoreAddress1>
<StoreCity>Lewiston</StoreCity>
<StoreState>WA</StoreState>
<StoreZip>98105</StoreZip>
</Store>
<Store>
<StoreName>Tammy's Grocey</StoreName>
<StoreAddress1>7555 Mockingbird Lane</StoreAddress1>
<StoreCity>Boise</StoreCity>
<StoreState>ID</StoreState>
<StoreZip>88105</StoreZip>
</Store>
<Store>
<StoreName>Franny's Grocey</StoreName>
<StoreAddress1>55 Bird Dr</StoreAddress1>
<StoreCity>Boise</StoreCity>
<StoreState>ID</StoreState>
<StoreZip>88105</StoreZip>
</Store>
<Store>
<StoreName>Joe's Grocey</StoreName>
<StoreAddress1>555 Dog bird Ln</StoreAddress1>
<StoreCity>Lewiston</StoreCity>
<StoreState>ID</StoreState>
<StoreZip>88105</StoreZip>
</Store>
</Stores>
<xsl:template name="doStateList">
<xsl:for-each select="Store[not(StoreState=preceding::StoreState)]">
<xsl:sort select="StoreState"/>
<h3><xsl:value-of select="StoreState"/></h3>
<xsl:call-template name="doCityList">
<xsl:with-param name="vStoreState" select="StoreState"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="doCityList">
<xsl:param name="vStoreState" select="'notPassed'"/>
<xsl:for-each select="//Store[StoreState=$vStoreState and not(StoreCity=preceding::StoreCity)]">
<!-- this is where the second not-preceding doesn't work for me as it starts at the document start and not within the current set of stores with the same StoreState -->
<xsl:value-of select="StoreCity"/>
</xsl:for-each>
</xsl:template>
thanks much for any help!
|
|
|
|