使用XSL将XML输出到HTML

时间:2013-07-07 14:20:37

标签: xml xslt

我有以下XML(简体)

<?xml version="1.0" encoding="UTF-8"?>
<REPOSITORY>
<VIEW UPDATED_BY="SADMIN">
    <VIEW_LOCALE  UPDATED_BY="SADMIN">  </VIEW_LOCALE>
    <VIEW_WEB_TEMPLATE UPDATED_BY="SADMIN" COMMENTS="TEST COMMENT">
        <VIEW_WEB_TEMPLATE_ITEM UPDATED_BY="SADMIN"></VIEW_WEB_TEMPLATE_ITEM>
        </VIEW_WEB_TEMPLATE>
    </VIEW>
<VIEW UPDATED_BY="USER">
    <VIEW_LOCALE  UPDATED_BY="USER">    </VIEW_LOCALE>
    <VIEW_WEB_TEMPLATE UPDATED_BY="USER">
        <VIEW_WEB_TEMPLATE_ITEM UPDATED_BY="USER"></VIEW_WEB_TEMPLATE_ITEM>
        <VIEW_WEB_TEMPLATE_ITEM UPDATED_BY="USER2"></VIEW_WEB_TEMPLATE_ITEM>
        </VIEW_WEB_TEMPLATE>
    </VIEW>
</REPOSITORY>

我需要遍历此XML并将输出打印为HTML表格。以下是我提出的XSL

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match ="/" >
<html><head></head>
<body>
  <xsl:apply-templates />
 </body>
 </html>
</xsl:template>

<xsl:template match="/" >
<xsl:for-each select="REPOSITORY/VIEW">
<table>
  <tr>
   <td>Updated By</td>
   <td><xsl:value-of select="@UPDATED_BY" /></td>
  </tr>
</table>
<xsl:if test="./VIEW_WEB_TEMPLATE">
    <table>
      <tr><td>Updated By</td><td>Comments</td></tr>
       <xsl:for-each select="*[name()='VIEW_WEB_TEMPLATE']">
        <tr>
            <td><xsl:value-of select="@UPDATED_BY" /></td>
            <td><xsl:value-of select="@COMMENTS" /></td>
        </tr>
        </xsl:for-each> <!-- end of view_web_template -->     
    </table>
    <xsl:if test="./VIEW_WEB_TEMPLATE_ITEM">
        <table>
        <tr><td>Updated by</td></tr>
            <xsl:for-each select="./VIEW_WEB_TEMPLATE_ITEM">
                <tr> 
                    <td><xsl:value-of select="@UPDATED_BY" /></td>
                </tr>
            </xsl:for-each> <!-- end of web_template_item -->
        </table>
    </xsl:if>
</xsl:if>
</xsl:for-each> <!-- end of view -->
</xsl:template>
</xsl:stylesheet>

我知道这可能不是最好的方法,但我无法在表格中获得 VIEW_WEB_TEMPLATE_ITEM 节点数据。 if条件失败。

我怀疑可能是因为for-each已经处理了 VIEW_WEB_TEMPLATE 节点。

所以我的XPATH应该是如果以前处理过的节点有子节点然后选择它但是我在XSLT中不够专业才能做到这一点。 任何指针??

1 个答案:

答案 0 :(得分:0)

XSLT不关心(或跟踪)已处理的节点。多次选择和处理相同的节点是完全有效的。

这种情况下的问题是上下文之一。第一个和第二个xsl:if语句具有相同的XSLT上下文,即VIEW元素。但要匹配VIEW_WEB_TEMPLATE_ITEM元素,上下文必须是VIEW_WEB_TEMPLATE元素。从纯粹的技术角度来看,您需要做的只是写<xsl:if select="VIEW_WEB_TEMPLATE/VIEW_WEB_TEMPLATE_ITEM">,条件将成立。

那就是说,在你的特定情况下,我想你会想要在<xsl:for-each>内移动第二个条件。然后它将处于正确的上下文中,因为<xsl:for-each>处理VIEW_WEB_TEMPLATE元素。