Combining result from apply-templates with for-each-group (or alternative solution to the problem)
I got a list of articles that is sorted based on their title. In addition to the "main"-title, articles may have alternative titles (and even mulitple of them). When articles are do have alternative titles, the article should be displayed as many times as there are titles (an article with main title and two alternative titles should make three entries in the list). Simon Christian on this forum posted a solution to overcome this (thanks), and I'm able to get the desired list.
However, I need to extend this solution. In addition to the list, I need a jump menu. So I have to extract the first letter of each title (including the alternative titles), take these letters and display them on the top of the list. Each letters is a link to an anchor on the page. In the list, first the letter 'A' may be presented, followed by all articles starting on 'A', then 'B' followed by all articles starting with 'B', and so on. Those letters that is not the first letter of any title, should not be displayed.
I have an old solution on how to get the jump menu, but it only works when I have to extract the title from one place in the source XML. The alternative titles are a couple of levels deeper than the main title. For the old solution I used:
<div class="jumpmenu">
<xsl:for-each-group group-by="substring(title, 1,1)" select="content">
<xsl:sort order="ascending" select="substring(title, 1,1)"/>
<a href="{$url}#{substring(title, 1,1)}"><xsl:value-of select="substring(title, 1,1)"/></a><xsl:text> </xsl:text>
</xsl:for-each-group>
</div>
But as mentioned, it does not take the alternative titles into account. I'm able to get the first letter of all title (including the alternatives) by using this:
<xsl:apply-templates select="content/title|content/contentdata/alternativetitles/alternativetitle" mode="jumpmenu">
&l开发者_如何转开发t;xsl:sort select="string(.)" />
</xsl:apply-templates>
It basically just gets the first letter of all titles and sort them. I've tried to find ways of combining these two (for-each-group and apply-templates), but without luck. Any ideas on how to do this. An example source XML is as follows:
<result>
<element>
<title>ATitle 1</title>
<alternative>
<alternativeTitle>Title 5<alternativeTitle>
</alternative>
<data>
...
</data>
</element>
<element>
<title>CTitle 3</title>
<alternative>
<alternativeTitle>BTitle 2<alternativeTitle>
<alternativeTitle>Title 4<alternativeTitle>
</alternative>
<data>
...
</data>
</element>
</result>
My desired output is something like:
A B C T (links to their respective anchors)
A (anchor)
ATITLE 1 (which is also a link to the full article)
B (anchor)
BTITLE 2 (which is also a link to the full article)
C (anchor)
CTITLE 3 (which is also a link to the full article)
T (anchor)
TITLE 4 (which is also a link to the full article)
TITLE 5 (which is also a link to the full article)
The solution to this will probably help me with another problem, but I'll present it if anyone got ideas for that as well. The articles that have alternative titles, are listed under the same letter as the first letter of the main title. So given the exmaple above, "BTitle 2" is listed under 'C'.
Sorry for the long post, I didn't find any way to make it shorter and still be precise. In advance, thanks!
EDIT: This the code I have so far on the second part of the problem:
<xsl:for-each-group group-by="substring(title, 1,1)" select="content">
<xsl:sort order="ascending" select="substring(title, 1,1)"/>
<xsl:apply-templates mode="overskrift" select="."/>
<xsl:apply-templates select="current-group()/title|current-group()/contentdata/alternativetitles/alternativetitle">
<xsl:sort select="string(.)"/>
</xsl:apply-templates>
</xsl:for-each-group>
That code will list all titles, but lists the alternative titles based on the same first letter as the article's main title..
Well why don't you simply use
<xsl:for-each-group select="content/title|content/contentdata/alternativetitles/alternativetitle" group-by="substring(., 1, 1)">
<xsl:sort select="current-grouping-key()"/>
<a href="{$url}#{current-grouping-key()}"><xsl:value-of select="current-grouping-key()"/></a><xsl:text> </xsl:text>
</xsl:for-each-group>
? You should put that code in a template matching the parent of that content element (I am not sure what name it has as your path expressions and the posted XML sample do not match).
精彩评论