Susan,
At 03:46 PM 11/11/2010, you wrote:
I am having problems in sorting using one of two possible values.I
have a template that creates an index using the indexterm element.
Here is a snippet of XML: <p>Here is an <indexterm>index
entry</indexterm> without an attribute, and the contents of the
element will display in the index. This <indexterm
term.entry="Alternate text">index entry</indexterm> does have an
attribute, and the contents of the attribute will display in the
index rather than the content of the indexterm element. </p> I need
to be able to sort the index using one of two possible values. If
the indexterm doesn't contain a term.entry attribute, it should sort
using the content of the indexterm element. If the indexterm element
contains a term.entry attribute, then it should sort using the value
of the term.entry attribute. I have the following that sorts the
index. The template outputs the value of the term.entry attribute if
present, but it sorts only using the content of the indexterm
element: <xsl:for-each-group
select="//indexterm" group-by="."> <xsl:sort
select="translate(text(),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<div class="index"> <xsl:choose> <xsl:when
test="@term.entry"><span><xsl:value-of
select="@term.entry"/><xsl:text> -
</xsl:text></span></xsl:when> <xsl:otherwise><span><xsl:value-of
select="."/><xsl:text> -
</xsl:text></span></xsl:otherwise> </xsl:choose>
</div> </xsl:for-each-group> How would I be able to sort the index
entries using the content of the indexterm element (when there is no
term.entry element) or the term.entry attribute for the indexterm
element (if present)? Thanks for any assistance with this. Susan
As I understand it, you want your sorting to use the value of the
@term.entry instead of the value of the element itself, when the
attribute is available.
But I think you actually want to work with the grouping key, not just
the sorting key. After all, you don't want the groups to be sorted on
something other than the values by which they are grouped, do you?
Something like this:
<xsl:for-each-group select="//indexterm" group-by="(@term.entry,text())[1])">
<xsl:sort select="current-grouping-key()"/>
<div class="index">
<span>
<xsl:value-of select="current-grouping-key()"/>
<xsl:text> - </xsl:text>
</span>
</div>
...
This declares as the grouping key the value of the first node that's
available for each selected node from among its @term.entry and its
text node children. So, it'll be the @term.entry for those indexterms
that have one, the first text node child for those that don't.
Also, I'd probably prefer "(@term.entry,.)[1])" to work around
potential issues with mixed content. But maybe you know you'll never
have those.
I'll let you wrap the expression in whatever munging functionality
you want. But note that XSLT 2.0, which you are using, has an
upper-case() function that works better than the old translate() trick.
You can also see the current-grouping-key() function here, saving
more conditional logic.
Good luck,
Wendell
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--