嘿,我有愚蠢的xml文件:
<?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>
我想通过dep应用xslt 1.0来获取事故数量:输出应该像这样的html页面:
<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>
谢谢,请注意我使用php5
答案 0 :(得分:1)
您可以使用与上一个问题几乎相同的答案:
<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>
将此转换应用于提供的XML文档:
<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>
生成了正确的结果(在标题中添加了“deps:”以实现正确对齐):
<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>
如果发生事故以外的其他事件和没有事故的部门,事情会变得更有趣。假设我们现在有这个XML文档:
<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>
这又是一次正确产生所有不同部门及其事故数量的转变:
<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>
当对上述XML文档应用此转换时,它会生成正确的,想要的结果:
<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>
更新:在评论中,OP还要求每个部门都有“com”的总和。
转化需要稍微改变:
<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>
现在,当应用于同一个XML文档(上图)时,再次生成想要的答案:
<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>
答案 1 :(得分:0)
使用:
<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>