3
votes

I'm working on a little XML/XSLT project and I'm having trouble retrieving more than one element from the XML file.

I want to retrieve the client name(Attribute) and the transaction amount(Attribute) but it doesn't work. The only element attribute I can output is client name.

I've tried to change <xsl:template match="client"> to <xsl:template match="list"> but then everything was showing and I don't want the question element to print.

Once names and amounts will output, I need to sum the amounts to show the total but first I really need to get the amounts to output. Any idea?

XML File :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet href="xslt.xml" 
type="application/xml"?>
<list> 
<client name="Morton"> 
<transaction amount="43" />
<question>Who?</question>
<transaction amount="21" /> 
</client> 
<client name="Mingus"> 
<transaction amount="6" /> 
<transaction amount="32" /> 
<question>Where?</question>
<transaction amount="45" /> 
</client> 
</list>

XSLT File :

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="client">
<html>
<body>

<p>Name:</p>
<xsl:apply-templates select="client" />
<xsl:value-of select="client" />
<xsl:value-of select="@name" />

<p>Total:</p>
<xsl:value-of select="transaction" />
<xsl:value-of select="@amount" />

</body>
</html>
</xsl:template>
</xsl:stylesheet>

Current Output Result:

Client:
Morton
Total:
Client:
Mingus
Total:

Desired Output Result:

Client: Morton
Total: 64
Client: Mingus
Total: 83
1
Can you add an example of your desired output?Daniel Haley
Of course, it's in there now! :)Simon L.

1 Answers

2
votes

The problem you're having is with your xpaths. Your context is client so all paths have to be relative to that. So if you're trying to get the amount attribute of a child transaction, the xpath would be transaction/@amount.

However, if you use <xsl:value-of select="transaction/@amount"/> and there are more than one transaction children, you'll only get the value of the first occurrence. (In XSLT 1.0 anyway. In XSLT 2.0 you'll get all of the values concatenated together.)

Here's how I would do this:

XML Input

<list> 
    <client name="Morton"> 
        <transaction amount="43" />
        <question>Who?</question>
        <transaction amount="21" /> 
    </client> 
    <client name="Mingus"> 
        <transaction amount="6" /> 
        <transaction amount="32" /> 
        <question>Where?</question>
        <transaction amount="45" /> 
    </client> 
</list>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="html"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/list">
        <html>
            <head></head>
            <body>
                <xsl:apply-templates select="client"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="client">
        <p>Client: <xsl:value-of select="@name"/></p>
        <p>Total: <xsl:value-of select="sum(transaction/@amount)"/></p>
    </xsl:template>

</xsl:stylesheet>

HTML Output

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   </head>
   <body>
      <p>Client: Morton</p>
      <p>Total: 64</p>
      <p>Client: Mingus</p>
      <p>Total: 83</p>
   </body>
</html>