如何将模板添加到使用for-each循环生成HTML的现有XSLT?

时间:2010-10-29 16:26:19

标签: xslt

我有一个为XML文件生成HTML的样式表。

示例XML文件:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="trial.xsl"?>
<wholeEnchilada>
  <Interface>
    <Messages>
      <Message name="blah">
        <Variable name="DialogIdentifier" dataType="UINT16"/>
        <Variable name="ReplyCount" dataType="UINT16"/>
        <Variable name="ReplyPeriod" dataType="UINT16"/>
      </Message>
      <Message>
        <Variable name="Uptime" dataType="UINT32"/>
        <Variable name="FaultIndicator" dataType="UINT32"/>
        <Variable name="OperatingMode" dataType="UINT8"/>
      </Message>
    </Messages>
  </Interface>
  <Interface>
    <Messages>
      <Message>
        <Variable name="vara" dataType="UINT64"/>
        <Variable name="varb" dataType="UINT8"/>
      </Message>
    </Messages>
  </Interface>
</wholeEnchilada>

示例样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <HTML>
      <BODY>
        <xsl:for-each select="*">
          <xsl:for-each select="Interface">
            <xsl:for-each select="Messages">
              <xsl:for-each select="Message">
                <TABLE BORDER="1">
                  <TR><TH>Field Name</TH><TH>Size</TH><TH>Offset</TH></TR>
                  <!-- Fields-->
                  <xsl:for-each select="Variable">
                    <TR>
                      <TD><xsl:value-of select="@name"/></TD>
                      <TD><xsl:value-of select="@size"/></TD>
                      <TD><xsl:value-of select="@offset"/></TD>
                    </TR>
                  </xsl:for-each> <!-- Fields-->
                </TABLE>
              <xsl:for-each select="Variable">
                <xsl:variable name="fieldSize" select="substring-after(@dataType,'INT') div 8"/>
                <TABLE BORDER="1">
                  <TR><TH>Name</TH>    <TH><xsl:value-of select="@name"/></TH></TR>
                  <TR><TD>Size</TD>    <TD><xsl:value-of select="$fieldSize"/></TD></TR>
                  <TR><TD>Offset</TD>  <TD><xsl:value-of select="Offset"/></TD></TR>
                  <TR><TD>DataType</TD><TD><xsl:value-of select="@dataType"/></TD></TR>
                </TABLE>
              </xsl:for-each>
                <hr size="10" noshade="true"/>
              </xsl:for-each>  <!-- Message -->
            </xsl:for-each> <!-- Messages -->
          </xsl:for-each> <!-- Interface -->
        </xsl:for-each> <!-- * -->
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

我的实际样式表长约300行,打印出更多属性,并导航比上面给出的样本更多的结构。

我问question有关如何计算字段大小(INT8-> 1,INT16-> 2,INT32-> 4)以及可变偏移量,其中第一个变量从0开始,下一个在第一个之后开始,等等。我认为这个问题已得到解答,但不幸的是,我已经完成了在现有样式表中集成答案以生成HTML的不成功。

我尝试从他的“编辑3”中整合Alejandro's answer,但根据输出,我做得不对:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="Variable">
        <xsl:param name="fieldOffset" select="0"/>
        <xsl:variable name="fieldSize" select="substring-after(@dataType,'INT') div 8"/>
        (<xsl:value-of select="@name"/>, <xsl:value-of select="$fieldSize"/>, <xsl:value-of select="$fieldOffset"/>)
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="size">
                <xsl:value-of select="$fieldSize"/>
            </xsl:attribute>
            <xsl:attribute name="offset">
                <xsl:value-of select="$fieldOffset"/>
            </xsl:attribute>
        </xsl:copy>
        ((<xsl:value-of select="@name"/>, <xsl:value-of select="@size"/>, <xsl:value-of select="@offset"/>))
        <xsl:apply-templates select="following-sibling::Variable[1]">
            <xsl:with-param name="fieldOffset" select="$fieldOffset + $fieldSize"/>
            <xsl:value-of select="@fieldOffset"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="/">
        <HTML>
          <BODY>
            <xsl:for-each select="*">
              <xsl:for-each select="Interface">
                <xsl:for-each select="Messages">
                  <xsl:for-each select="Message">
                    <TABLE BORDER="1">
                      <TR><TH>Field Name</TH><TH>Size</TH><TH>Offset</TH></TR>
                      <!-- Fields-->
                      <xsl:for-each select="Variable">
                        <xsl:apply-templates select="*[1]|following-sibling::*[1]"/>
                        <TR>
                          <TD><xsl:value-of select="@name"/></TD>
                          <TD><xsl:value-of select="@size"/></TD>
                          <TD><xsl:value-of select="@offset"/></TD>
                        </TR>
                      </xsl:for-each> <!-- Fields-->
                    </TABLE>
              <xsl:for-each select="Variable">
                <xsl:variable name="fieldSize" select="substring-after(@dataType,'INT') div 8"/>
                <TABLE BORDER="1">
                  <TR><TH>Name</TH>    <TH><xsl:value-of select="@name"/></TH></TR>
                  <TR><TD>Size</TD>    <TD><xsl:value-of select="$fieldSize"/></TD></TR>
                  <TR><TD>Offset</TD>  <TD><xsl:value-of select="Offset"/></TD></TR>
                  <TR><TD>DataType</TD><TD><xsl:value-of select="@dataType"/></TD></TR>
                </TABLE>
              </xsl:for-each>
                    <hr size="10" noshade="true"/>
                  </xsl:for-each>  <!-- Message -->
                </xsl:for-each> <!-- Messages -->
              </xsl:for-each> <!-- Interface -->
            </xsl:for-each> <!-- * -->
          </BODY>
        </HTML>
    </xsl:template>
</xsl:stylesheet>

基于我的诊断语句(显示在HTML输出中的括号中),模板正在执行,我只是不知道如何从模板中显示正确的输出在HTML中。 xsl:copy似乎是创建节点的副本并将新属性@size和@offset放在其中,但不能使我的<xsl:value-of select="@size"/><xsl:value-of select="@offset"/>语句可以访问这些属性。< / p>

这是我想要获取的HTML,用于XML文件中的第一条消息:

<table border="1">
  <tbody>
    <tr><th>Field Name</th><th>Size</th><th>Offset</th></tr>
  </tbody>
  <tbody>
    <tr><td>DialogIdentifier</td><td>2</td><td>0</td></tr>
    <tr><td>ReplyCount</td><td>2</td><td>2</td></tr>
    <tr><td>ReplyPeriod</td><td>2</td><td>4</td>
    </tr></tbody>
</table>

<table border="1">
  <tbody>
    <tr><th>Name</th><th>DialogIdentifier</th></tr>
    <tr><td>Size</td><td>2</td></tr>
    <tr><td>Offset</td><td>0</td></tr>
    <tr><td>DataType</td><td>UINT16</td></tr>
  </tbody>
</table>
<table border="1">
  <tbody>
    <tr><th>Name</th><th>ReplyCount</th></tr>
    <tr><td>Size</td><td>2</td></tr>
    <tr><td>Offset</td><td>2</td></tr>
    <tr><td>DataType</td><td>UINT16</td></tr>
  </tbody>
</table>
<table border="1">
  <tbody>
    <tr><th>Name</th><th>ReplyPeriod</th></tr>
    <tr><td>Size</td><td>2</td></tr>
    <tr><td>Offset</td><td>4</td></tr>
    <tr><td>DataType</td><td>UINT16</td></tr>
  </tbody>
</table>

2 个答案:

答案 0 :(得分:2)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <xsl:template match="Message">
        <table border="1">
            <tbody>
                <tr>
                    <th>Field Name</th>
                    <th>Size</th>
                    <th>Offset</th>
                </tr>
            </tbody>
            <tbody>
                <xsl:apply-templates select="Variable[1]"/>
            </tbody>
        </table>
        <xsl:apply-templates select="Variable[1]" mode="table"/>
    </xsl:template>
    <xsl:template match="Variable">
        <xsl:param name="pOffset" select="0"/>
        <xsl:variable name="vSize"
                      select="substring-after(@dataType,'UINT') div 8"/>
        <tr>
            <td>
                <xsl:value-of select="@name"/>
            </td>
            <td>
                <xsl:value-of select="$vSize"/>
            </td>
            <td>
                <xsl:value-of select="$pOffset"/>
            </td>
        </tr>
        <xsl:apply-templates select="following-sibling::Variable[1]">
            <xsl:with-param name="pOffset" select="$pOffset + $vSize"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="Variable" mode="table">
        <xsl:param name="pOffset" select="0"/>
        <xsl:variable name="vSize"
                      select="substring-after(@dataType,'UINT') div 8"/>
        <table border="1">
            <tbody>
                <tr>
                    <th>Name</th>
                    <th>
                        <xsl:value-of select="@name"/>
                    </th>
                </tr>
                <tr>
                    <td>Size</td>
                    <td>
                        <xsl:value-of select="$vSize"/>
                    </td>
                </tr>
                <tr>
                    <td>Offset</td>
                    <td>
                        <xsl:value-of select="$pOffset"/>
                    </td>
                </tr>
                <tr>
                    <td>DataType</td>
                    <td>
                        <xsl:value-of select="@dataType"/>
                    </td>
                </tr>
            </tbody>
        </table>
        <xsl:apply-templates select="following-sibling::Variable[1]"
                             mode="table">
            <xsl:with-param name="pOffset" select="$pOffset + $vSize"/>
        </xsl:apply-templates>
    </xsl:template>
</xsl:stylesheet>

输出:

<table border="1">
    <tbody>
        <tr>
            <th>Field Name</th>
            <th>Size</th>
            <th>Offset</th>
        </tr>
    </tbody>
    <tbody>
        <tr>
            <td>DialogIdentifier</td>
            <td>2</td>
            <td>0</td>
        </tr>
        <tr>
            <td>ReplyCount</td>
            <td>2</td>
            <td>2</td>
        </tr>
        <tr>
            <td>ReplyPeriod</td>
            <td>2</td>
            <td>4</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>DialogIdentifier</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>2</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>0</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT16</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>ReplyCount</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>2</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>2</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT16</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>ReplyPeriod</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>2</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>4</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT16</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Field Name</th>
            <th>Size</th>
            <th>Offset</th>
        </tr>
    </tbody>
    <tbody>
        <tr>
            <td>Uptime</td>
            <td>4</td>
            <td>0</td>
        </tr>
        <tr>
            <td>FaultIndicator</td>
            <td>4</td>
            <td>4</td>
        </tr>
        <tr>
            <td>OperatingMode</td>
            <td>1</td>
            <td>8</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>Uptime</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>4</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>0</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT32</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>FaultIndicator</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>4</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>4</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT32</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>OperatingMode</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>8</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT8</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Field Name</th>
            <th>Size</th>
            <th>Offset</th>
        </tr>
    </tbody>
    <tbody>
        <tr>
            <td>vara</td>
            <td>8</td>
            <td>0</td>
        </tr>
        <tr>
            <td>varb</td>
            <td>1</td>
            <td>8</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>vara</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>8</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>0</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT64</td>
        </tr>
    </tbody>
</table>
<table border="1">
    <tbody>
        <tr>
            <th>Name</th>
            <th>varb</th>
        </tr>
        <tr>
            <td>Size</td>
            <td>1</td>
        </tr>
        <tr>
            <td>Offset</td>
            <td>8</td>
        </tr>
        <tr>
            <td>DataType</td>
            <td>UINT8</td>
        </tr>
    </tbody>
</table>

答案 1 :(得分:0)

现在要经历太多,但这里有一些资源和提示。

  1. 这是w3c学校的链接 在线教程: http://www.w3schools.com/xsl/default.asp

  2. 如果你接受它,或者绝望 够了,你也可以查看了 眼镜。有关其他细节: http://www.w3.org/TR/xslt

  3. 使用Firefox。它显示了哪里 错误对你有很大帮助 在调试时。