Reputation: 323
Hey i have the foolowing xml file :
<?xml version="1.0"?>
<accidents>
<accident>
<org>1</org>
<com>194</com>
<dep>010</dep>
<grav>0.64</grav>
</accident>
<accident>
<org>1</org>
<com>194</com>
<dep>420</dep>
<grav>0.54</grav>
</accident>
<accident>
<org>1</org>
<com>44</com>
<dep>010</dep>
<grav>0.4</grav>
</accident>
</accidents>
And i want to apply an xslt 1.0 to have the number of accidents by dep : the output should be as an html page like this :
<table> <thead> <tr> <th>420</th> <th>010</th> </tr> </thead> <tbody> <tr>
<th>accidents</th> <td>1</td> <td>2</td> </tr> </tbody> </table>
thanks ,note i use php5
Upvotes: 0
Views: 179
Reputation: 243569
You can use almost the same answer as that to your previous question:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kAccByDept" match="accident" use="dep"/>
<xsl:template match="/*">
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<xsl:apply-templates/>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<xsl:apply-templates mode="count"/>
</tr>
</tbody>
</table>
</html>
</xsl:template>
<xsl:template match=
"accident
[generate-id()
=
generate-id(key('kAccByDept', dep)[1])
]">
<td><xsl:value-of select="dep"/></td>
</xsl:template>
<xsl:template mode="count" match=
"accident
[generate-id()
=
generate-id(key('kAccByDept', dep)[1])
]">
<td><xsl:value-of select="count(key('kAccByDept', dep))"/></td>
</xsl:template>
<xsl:template match="text()"/>
<xsl:template match="text()" mode="count"/>
</xsl:stylesheet>
When this transformation is applied to the provided XML document:
<accidents>
<accident>
<org>1</org>
<com>194</com>
<dep>010</dep>
<grav>0.64</grav>
</accident>
<accident>
<org>1</org>
<com>194</com>
<dep>420</dep>
<grav>0.54</grav>
</accident>
<accident>
<org>1</org>
<com>44</com>
<dep>010</dep>
<grav>0.4</grav>
</accident>
</accidents>
the correct result is produced (with added "deps:" in the heading to achieve proper alignment):
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<td>010</td>
<td>420</td>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<td>2</td>
<td>1</td>
</tr>
</tbody>
</table>
</html>
Things become more interesting if there are other events than accidents and departments without accidents. Suppose we now have this XML document:
<events>
<accidents>
<accident>
<org>1</org>
<com>194</com>
<dep>010</dep>
<grav>0.64</grav>
</accident>
<accident>
<org>1</org>
<com>194</com>
<dep>420</dep>
<grav>0.54</grav>
</accident>
<accident>
<org>1</org>
<com>44</com>
<dep>010</dep>
<grav>0.4</grav>
</accident>
</accidents>
<achievements>
<achievement>
<org>1</org>
<com>194</com>
<dep>002</dep>
<grav>0.64</grav>
</achievement>
<achievement>
<org>1</org>
<com>194</com>
<dep>420</dep>
<grav>0.54</grav>
</achievement>
<achievement>
<org>1</org>
<com>44</com>
<dep>011</dep>
<grav>0.4</grav>
</achievement>
</achievements>
</events>
Here is again a transformation which correctly produces all different departments and their number of accidents:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kAccByDept" match="accident" use="dep"/>
<xsl:key name="kDepByCode" match="dep" use="."/>
<xsl:variable name="vDeps" select=
"/*/*/*/dep
[generate-id()
=
generate-id(key('kDepByCode', .)[1])
]
"/>
<xsl:template match="/*">
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<xsl:apply-templates select="$vDeps"/>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<xsl:apply-templates select="$vDeps" mode="acc"/>
</tr>
</tbody>
</table>
</html>
</xsl:template>
<xsl:template match="dep">
<td><xsl:value-of select="."/></td>
</xsl:template>
<xsl:template match="dep" mode="acc">
<td><xsl:value-of select="count(key('kAccByDept', .))"/></td>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the above XML document, it produces the correct, wanted result:
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<td>010</td>
<td>420</td>
<td>002</td>
<td>011</td>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<td>2</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
</html>
UPDATE: In a comment the OP asked also to have the sum of "com" per department.
The transformation needs to changed only slightly:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kAccByDept" match="accident" use="dep"/>
<xsl:key name="kDepByCode" match="dep" use="."/>
<xsl:variable name="vDeps" select=
"/*/*/*/dep
[generate-id()
=
generate-id(key('kDepByCode', .)[1])
]
"/>
<xsl:template match="/*">
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<xsl:apply-templates select="$vDeps"/>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<xsl:apply-templates select="$vDeps" mode="acc"/>
</tr>
<tr>
<th>coms:</th>
<xsl:apply-templates select="$vDeps" mode="com"/>
</tr>
</tbody>
</table>
</html>
</xsl:template>
<xsl:template match="dep">
<td><xsl:value-of select="."/></td>
</xsl:template>
<xsl:template match="dep" mode="acc">
<td><xsl:value-of select="count(key('kAccByDept', .))"/></td>
</xsl:template>
<xsl:template match="dep" mode="com">
<td><xsl:value-of select="sum(key('kAccByDept', .)/com)"/></td>
</xsl:template>
</xsl:stylesheet>
Now, when applied on the same XML document (above), again the wanted answer is produced:
<html>
<table border="1">
<thead>
<tr>
<th>deps:</th>
<td>010</td>
<td>420</td>
<td>002</td>
<td>011</td>
</tr>
</thead>
<tbody>
<tr>
<th>accidents:</th>
<td>2</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th>coms:</th>
<td>238</td>
<td>194</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
</html>
Upvotes: 1
Reputation: 56202
Use:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k" match="accident" use="dep"/>
<xsl:template match="/accidents">
<xsl:variable name="accidents" select="accident[generate-id()
= generate-id(key('k', dep))]"/>
<table>
<thead>
<tr>
<xsl:for-each select="$accidents">
<th>
<xsl:value-of select="dep"/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<tr>
<xsl:for-each select="$accidents">
<td>
<xsl:value-of select="count(key('k', dep))"/>
</td>
</xsl:for-each>
</tr>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0