Retrieving multiple values from an attribute

Here should go questions about transforming XML with XSLT and FOP.
rexsavior
Posts: 3
Joined: Wed Dec 01, 2004 4:19 am

Retrieving multiple values from an attribute

Post by rexsavior »

Hi, I have an attribute that has several values separated by whitespace.

Like so: <speech who="david bob alan">

I would like to retrieve all three names, but of course calling @who only retrieves the first name.

What am I doing wrong?
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Small Test

Post by Radu »

Hi,
I applied to this small xml file:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<speech who="david bob alan">
</speech>
this small stylesheet:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:value-of select="//@who"/>
</xsl:template>
</xsl:stylesheet>
and it works with no problem, the output is:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>david bob alan
Basically calling an attribute returns the whole attribute's value (it retrieves everything between the quotes).
I recommand you try to check if the xpath expression in your "xsl:valueof" tag retrieves the attribute value from the right element.

Please tell us if you have any more problems and if you do, maybe small samples of your files would be of help.
rexsavior
Posts: 3
Joined: Wed Dec 01, 2004 4:19 am

More info

Post by rexsavior »

Ah, I didn't give nearly enough info. Sorry for that, and thank you for response just the same.

I'm actually trying to grab these attribute IDs and create variables from them for matching with the complete speakers name (encoded in the header). Here's some actual code, first my XML:

Code: Select all


<header>
<speakers>
<speaker id="abe">Abraham Lincoln</speaker>
<speaker id="steve">Stephen Douglass</speaker>
</speakers>
</header>
<text>
<speech speakers="abe steve">
<statement/>
</speech>
</text>
I'd like the XSL to print out (for each speech, in the 'text' section) each speakers full name. Like so:

Code: Select all


<xsl:template match="speech">
<xsl:variable name="myVar" select="@speakers"/>
<xsl:for-each select="//header/speakers/speaker">
<xsl:if test="@id = $myVar">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
So, this works to some degree. It creates a variable of the first name listed in the speakers attribute, matches it with the speaker id in the header and prints out 'Abraham Lincoln.' But steve is there too, and I'd like it to print out that name as well.

Thanks again for help.
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

I guess you are looking for something like below.

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:template match="speech">
<xsl:variable name="myVar" select="@speakers"/>
<xsl:for-each select="//header/speakers/speaker[contains($myVar, @id)]">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
will give as output:

Code: Select all


Abraham Lincoln, Stephen Douglass
Best Regards,
George
rexsavior
Posts: 3
Joined: Wed Dec 01, 2004 4:19 am

Thanks

Post by rexsavior »

That does the trick! Thanks so much for the help. I'm still not sure why my original if-test wasn't working, but I do see why this one *does* work - which is a start!
Post Reply