 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

June 12th, 2009, 08:30 AM
|
|
Friend of Wrox
|
|
Join Date: Feb 2009
Posts: 119
Thanks: 25
Thanked 3 Times in 3 Posts
|
|
XSLT 1.0 sort issue
Hello all,
using XSLT 1.0 I want to sort a Name first by Last name then by first name.
The problem is that the Name which contains first name followed by last name can sometimes have either a space or a comma between the first and last.
Any ideas?
Thanks in advance.
|
|

June 12th, 2009, 08:49 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Code:
<xsl:apply-templates select="Foo">
<xsl:sort select="substring-after(translate(Name, ', ', '|'), '|')"/>
<xsl:sort select="substring-before(translate(Name, ', ', '|'), '|')"/>
</xsl:apply-templates>
That replaces both comma and space with a '|' bar character and then extracts the last name as the substring after the bar character and the first name as the substring before the bar character.
If that does not help then please show us a sample of the XML you have.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

June 12th, 2009, 09:07 AM
|
|
Friend of Wrox
|
|
Join Date: Feb 2009
Posts: 119
Thanks: 25
Thanked 3 Times in 3 Posts
|
|
That doesn't seem to do the job. Here is a sample of the xml
Code:
<student>
<dummyLabel/>
<studentName>insert student,aaaa</studentName>
<studentLink>http://</studentLink>
<studentPhoto>
<path>/</path>
</studentPhoto>
<studentStatus>Pending</studentStatus>
<graduationMonth>..</graduationMonth>
<graduationYear>..</graduationYear>
</student>
<student>
<dummyLabel/>
<studentName>ansert studentt, aaaa</studentName>
<studentLink>http://</studentLink>
<studentPhoto>
<path>/</path>
</studentPhoto>
<studentStatus>Pending</studentStatus>
<graduationMonth>..</graduationMonth>
<graduationYear>..</graduationYear>
</student>
<student>
<dummyLabel/>
<studentName>ansert aaaa</studentName>
<studentLink>http://</studentLink>
<studentPhoto>
<path>/</path>
</studentPhoto>
<studentStatus>Pending</studentStatus>
<graduationMonth>..</graduationMonth>
<graduationYear>..</graduationYear>
</student>
<student>
<dummyLabel/>
<studentName>ansert bbb</studentName>
<studentLink>http://</studentLink>
<studentPhoto>
<path>/</path>
</studentPhoto>
<studentStatus>Pending</studentStatus>
<graduationMonth>..</graduationMonth>
<graduationYear>..</graduationYear>
</student>
Regards,
John Bampton.
|
|

June 12th, 2009, 09:10 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
In "ansert studentt, aaaa", what are the first name and last name?
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

June 12th, 2009, 09:17 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
So I assume you want to sort 'student' elements by the 'studentName' child element. Your first post said "can sometimes have either a space or a comma between the first and last" so I assumed you would have either e.g.
<studentName>First,Last</studentName>
or
<studentName>First Last</studentName>
where I think my suggestion would work.
However in the sample you posted you have both spaces and commas as for instance in <studentName>ansert studentt, aaaa</studentName>. What would be the first name and the last name in that sample, is the first name "ansert studentt" and the last "aaaa"?
It might be better to approach the problem with two passes where the first pass extracts the name components into elements or attributes of its own and the second pass sorts. Can you use exsl:node-set with your XSLT 1.0 processor? Do you perhaps have EXSLT regular expression support to split up those names?
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

June 12th, 2009, 09:19 AM
|
|
Friend of Wrox
|
|
Join Date: Feb 2009
Posts: 119
Thanks: 25
Thanked 3 Times in 3 Posts
|
|
Hi Michael,
thanks for taking the time to respond. In that case the last name would be aaaa and the first name would be ansert student.
Lets just try for an example where first name and last name are both one word and they are either separated with a space or a comma or a comma followed by a space
ie.
' '
', '
','
Regards,
John Bampton.
|
|

June 12th, 2009, 09:23 AM
|
|
Friend of Wrox
|
|
Join Date: Feb 2009
Posts: 119
Thanks: 25
Thanked 3 Times in 3 Posts
|
|
Hi Martin, thanks for your responses.
I just found out we can use EXSLT and the processor is Xalan.
Regards
|
|

June 12th, 2009, 10:15 AM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
The problem with Martin's solution is that it should have two | in the tranpose function, so that both a space and a comma are replaced by pipes. This doesn't get around the problem where both a space and a comma are found in the name however.
Code:
<xsl:sort select="substring-after(translate(Name, ', ', '||'), '|')"/>
|
|

June 12th, 2009, 10:15 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Here is an attempt to solve that with XSLT 1.0 and ESLT node-set and string functions:
Code:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
xmlns:str="http://exslt.org/strings"
exclude-result-prefixes="exsl str">
<xsl:template match="students">
<xsl:variable name="students">
<xsl:apply-templates select="student" mode="change"/>
</xsl:variable>
<xsl:apply-templates select="exsl:node-set($students)/student"/>
</xsl:template>
<xsl:template match="student" mode="change">
<xsl:copy>
<xsl:apply-templates mode="change"/>
</xsl:copy>
</xsl:template>
<xsl:template match="student/studentName" mode="change">
<xsl:variable name="comp" select="str:tokenize(translate(., ', ', '||'), '|')"/>
<name>
<first>
<xsl:for-each select="$comp[position() != last()]">
<xsl:value-of select="."/>
<xsl:if test="position() != last()"><xsl:text> </xsl:text></xsl:if>
</xsl:for-each>
</first>
<last>
<xsl:value-of select="$comp[last()]"/>
</last>
</name>
</xsl:template>
<xsl:template match="stundent/*" mode="change">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="student">
<!-- process, this example simply copies -->
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
It replaces any comma and space in the studentName with a bar, then tokenizes on the bar and assumes the last token found is the last name while any tokens before that are concatenated as the first name. I am not sure that is exactly what you want but it should give you an idea at least how to implement your exact requirements. I tested that with the latest Xalan Java version.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

June 12th, 2009, 10:57 AM
|
|
Friend of Wrox
|
|
Join Date: Feb 2009
Posts: 119
Thanks: 25
Thanked 3 Times in 3 Posts
|
|
Hi Martin, thanks for that.
But the whole point of the question was to sort the students?
Regards,
John Bampton.
|
|
 |