我有一个XML文件,我使用XSL将其转换为html页面。我想循环遍历包含许多父节点的XML文件,然后循环遍历子节点并在HTML表中显示结果。
到目前为止,我能够循环遍历父节点并成功返回它们,但是当我在其中嵌套一个for-each循环以返回子节点的属性时,我最终返回文档中所有子节点的属性,而不是特定于父节点的属性。有谁能解释一下吗?
XML:<AdminReports xmlns="30/11/2011 09:25:58">
<AdminReport ID="1">
<DataSourceInformation DataSourceID="12" Value="DSI_50"/>
</AdminReport>
<AdminReport ID="2">
<DataSourceInformation DataSourceID="23" Value="DSI_30"/>
</AdminReport>
<AdminReport ID="3">
<DataSourceInformation DataSourceID="34" Value="DSI_20"/>
</AdminReport>
</AdminReports>
XSL: <table border="1" cellspacing="2" width="800" bgcolor="white">
<xsl:for-each select="/*/*[name()='AdminReport']">
<tr bgcolor="9acd32">
<table><th>Admin Report Num:</th></table>
<table><th><xsl:value-ofselect="@ID"/> </th></table>
</tr>
<tr>
<xsl:for-each select="/*/*/*[name()='DataSourceInformation']">
<table><th>Data Report ID:</th></table>
<table><th><xsl:value-of select="@DataSourceID"/></th></table>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
使用模板来代替for-each
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="30/11/2011 09:25:58">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<table border="1" cellspacing="2" width="800" bgcolor="white">
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="x:AdminReport">
<tr bgcolor="9acd32">
<table><th>Admin Report Num:</th></table>
<table><th><xsl:value-of select="@ID"/></th></table>
</tr>
<tr><xsl:apply-templates/></tr>
</xsl:template>
<xsl:template match="x:DataSourceInformation">
<table><th>Data Report ID:</th></table>
<table><th><xsl:value-of select="@DataSourceID"/></th></table>
</xsl:template>
</xsl:stylesheet>
指出:
- 每个部分都有自己的模板,它更清楚地构造了样式表
- 将来使用这种方法处理新元素会更容易
- 我将您的名称空间注册为前缀
x
,以便我可以引用x:DataSourceInformation
等元素而不是*[name()='DataSourceInformation']
XSLT中很少需要 -
for-each
;模板几乎总是更自然的解决方案 如果你坚持
for-each
,那么看看@GSerg的回答你把事情弄得太复杂了。
select
相对于当前上下文节点:
<table border="1" cellspacing="2" width="800" bgcolor="white">
<xsl:for-each select="/*/*[name()='AdminReport']">
<tr bgcolor="9acd32">
<table><th>Admin Report Num:</th></table>
<table><th><xsl:value-of select="@ID"/> </th></table>
</tr>
<tr>
<xsl:for-each select="*[name()='DataSourceInformation']">
<table><th>Data Report ID:</th></table>
<table><th><xsl:value-of select="@DataSourceID"/></th></table>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
更容易将XSLT看作声明性模板匹配引擎。查看此示例中的xsl:template和xsl:apply-template元素。最美好的祝福!
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="30/11/2011 09:25:58">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ns:AdminReports">
<table border="1" cellspacing="2" width="800" bgcolor="white">
<xsl:apply-templates select="ns:AdminReport"/>
</table>
</xsl:template>
<xsl:template match ="ns:AdminReport">
<tr bgcolor="9acd32">
<th>Admin Report Num:</th>
<th>
<xsl:value-of select="@ID"/>
</th>
</tr>
<tr>
<xsl:apply-templates select="ns:DataSourceInformation" />
</tr>
</xsl:template>
<xsl:template match="ns:DataSourceInformation" >
<table>
<th>Data Report ID:</th>
</table>
<table>
<th>
<xsl:value-of select="@DataSourceID"/>
</th>
</table>
</xsl:template>
</xsl:stylesheet>
value-of &选择
<xsl:value-ofselect="@ID"/>
应该是<xsl:value-of select="@ID"/>