XSL XML循环

时间:2011-12-06 19:31:42

标签: xml xslt

我有一个XML文件,我使用XSL转换为html页面。我想循环遍历包含许多父节点的XML文件,然后遍历子节点并在HTML表中显示结果。

到目前为止,我能够遍历Parent节点并成功返回它们,但是当我在其中嵌入 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>

4 个答案:

答案 0 :(得分:2)

使用模板而不是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的回答

答案 1 :(得分:1)

你过度复杂了。

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>

答案 2 :(得分:1)

将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>

答案 3 :(得分:0)

&amp;之间没有空格选择

<xsl:value-ofselect="@ID"/>

应为<xsl:value-of select="@ID"/>