XML / XSLT Attribute Output
I am working on a small XML / XSLT project and I am unable to get more than one element from the XML file.
I want to get the customer name (Attribute) and the transaction amount (Attribute), but that won't work. The only attribute on an element that I can display is client-side name
.
I tried to change <xsl:template match="client">
to <xsl:template match="list">
but then everything showed and I don't want the question item to be printed.
Once the names and amounts are displayed, I need to sum the amounts to show the total, but first I really need to get the amounts to be displayed. 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>
Output current result:
Client:
Morton
Total:
Client:
Mingus
Total:
Desired output result:
Client: Morton
Total: 64
Client: Mingus
Total: 83
source to share
The problem you are having is with your xpaths. Your context client
, so all paths should be relative to that. So if you are trying to get the attribute of the amount
child the transaction
xpath will be transaction/@amount
.
However, if you use <xsl:value-of select="transaction/@amount"/>
and have multiple children transaction
, you will only get the value of the first occurrence. (In XSLT 1.0, anyway. In XSLT 2.0, you get all the values ββconcatenated together.)
This is how I would do it:
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>
source to share