general xml/xpath functionality question

I have recently been working with XSL and XPath, and I've run across a problem implementing an Xpath expression I believe should work but for some reason doesn't. Rather than list the multitudes of trial and error xpath I've written, I will pose the problem in terms of an example. I am wondering whether this is a straightforward Xpath task, or if I am asking too much of xpath.

imagine you have an xml file of the following structure

<school>
<teacher>
<student> Bobby Fischer </student>
<classroom> 23 </classroom>
</teacher>
<teacher>
<student> Michael Douglas </student>
<classroom> 14 </classroom>
</teacher>
<teacher>
<student> Frank Zappa </student>
<classroom> 55 </classroom>
</teacher>
</school>

For the sake of this example, assume that each teacher only has one student.

If I wanted to gather all of the students names into a single variable, or put into a single place in a template via the

<xsl:value-of select="(code)"/> command, is their a way using xpath to gather all of the student names without returning the classrooms as well?

Most of the solutions I've tried previously entailed using the full-length axis names such as descendant::name (along with the associated node test) or predicates, but in most cases my resulting variable is either empty or contains only the first student's name.

My conclusion has been that using xpath expressions, though you can refer to a list of nodes, when doing an assignment via the <xsl:value-of .../> xpath will always choose a single node as a result.

Any comments would be appreciated
[1956 byte] By [mrUnderdog0] at [2007-11-19 12:45:53]
# 1 Re: general xml/xpath functionality question
Rather than list the multitudes of trial and error xpath I've written, I will pose the problem in terms of an example.

If you want help with something you should always, always, always provide a complete example of what you have tried, even though it doesn't work.

Given what you have posted the only thing I'am willing to tell you is that the XML you have posted is invalid. There is a </teacher> tag missing.

Oh, and I do know the answer to your question.
khp at 2007-11-10 3:27:18 >
# 2 Re: general xml/xpath functionality question
So just to give a few examples...

<xsl:value-of select="school"/> returns all of the text (teachers and classrooms) contained between descendant tags. This I expect

my first inclination was to try

<xsl:value-of select="school//student"/>

however this returns only the text "Bobby Fischer" and nothing else.

Next I tried a more verbose statement

<xsl:value-of select="school/descendant::student"/>

which yielded similar results.

Following that I tried predicates,

<xsl:value-of select="school//*[.=descendant::student"/>

Now I believe the line above is faulty, as it return no text at all. I tried several permutations of the above (as my syntax is by no means fluent) but I couldn't get something that yielded the results I was looking for.
mrUnderdog0 at 2007-11-10 3:28:18 >
# 3 Re: general xml/xpath functionality question
When you use a xsl:value-of statement the result of the 'select' is converted to a string value and printed.
This conversion is done using the string() xpath function, which works as follows.
A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order.

In other words what you are asking can't be done purely in XPath, you should setup a template for students and use xsl:apply-templates instead of xsl:value-of

Something like.

<xsl:template match="/">
<xsl:apply-templates select="//student"/>
</xsl:template>

<template match="student">
<xsl:value-of select="text()"/>
</xsl:template>

Of course in this case the template for student is a bit redundant, because it doesn't do anything different that what the default template would do for student nodes. So it could be omitted.
khp at 2007-11-10 3:29:17 >
# 4 Re: general xml/xpath functionality question
thanks for the solution. this is the answer I was looking for.
mrUnderdog0 at 2007-11-10 3:30:25 >
# 5 Re: general xml/xpath functionality question
You might then ask why does <xsl:value-of select="school"/> return all the text ?

This is also covered by the W3C.
The string-value of an element node is the concatenation of the string-values of all text node descendants of the element node in document order.
khp at 2007-11-10 3:31:24 >