XSL循环未返回正确的值



我想创建一个XSL循环来处理XML,如下所示:

<pop name="TEST">
<server>
   <name>host1</name>
      <status>red</status>
      <staleric>
        <ric service="A" name="a" />
        <ric service="A" name="b" />
        <ric service="A" name="c" />
        <ric service="A" name="d" />
        <ric service="A" name="e" />
        <ric service="A" name="f" />
      </staleric>
</server>
<server>
   <name>host2</name>
     <status>green</status>
</server>
<server>
   <name>host3</name>
     <status>red</status>
     <staleric>
      <ric service="B" name="1" />
      <ric service="B" name="2" />
     </staleric>
</server>
</pop>

XSL文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"
              doctype-system="about:legacy-compat"
              encoding="UTF-8"
              indent="yes" />
  <xsl:template match="/">
    <html>
      <head>
        <title>Distribution POP Green Light</title>
        <link rel="stylesheet" href="../index_files/staleric.css" />
      </head>
      <body>
        <table class="staleric">
          <thead>
            <tr>
              <td>POP :</td><td><xsl:value-of select="pop/@name"/></td>
            </tr>
            <tr>
              <th>Server</th>
              <th>Status</th>
              <th>Stale RIC</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="pop/server">
            <tr>
              <td><xsl:value-of select="name"/></td>
              <td>
                <xsl:variable name="statusTxt" select="status" />
                <xsl:choose>
                <xsl:when test="$statusTxt = 'red'">
                        <img src="../images/red.png"></img>
                </xsl:when>
                <xsl:otherwise>
                        <img src="../images/green.png"></img>
                </xsl:otherwise>
       </xsl:choose>
              </td>
              <td>
                <xsl:call-template name ="incr">
                        <xsl:with-param name ="value">1</xsl:with-param>
                        <xsl:with-param name ="limit">
                        <xsl:value-of select ="count(staleric/*)"/>
                        </xsl:with-param>
                </xsl:call-template>
              </td>
            </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>
<xsl:template name="incr">
  <xsl:param name="value"/>
  <xsl:param name ="limit"/>
  <xsl:if test ="$value!=$limit+1">
    Service : <xsl:value-of select ="//ric[$value]/@service"/>
    RIC : <xsl:value-of select ="//ric[$value]/@name"/>
    <br/>
    <xsl:if test ="$value mod $limit =0">
    </xsl:if>
    <xsl:call-template name ="incr">
      <xsl:with-param name ="value" select ="$value+1"/>
      <xsl:with-param name ="limit" select ="$limit"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>
</xsl:stylesheet>

参考XML文件,host3必须是服务B,RIC名称=1,2。不幸的是,我运行脚本后得到的结果是服务B和RIC名称=a,B。有人能解释一下或帮我解决吗?

Server                Status                Stale
host1                  red                  Service : A RIC : a
                                            Service : A RIC : b
                                            Service : A RIC : c
                                            Service : A RIC : d
                                            Service : A RIC : e
                                            Service : A RIC : f
host2                  green                
host3                  red                  Service : A RIC : a
                                            Service : A RIC : b

incr模板中:

<xsl:value-of select ="//ric[$value]/@service"/>

将始终为您提供来自输入文档中第一个服务器的结果,而不一定是for-each1迭代的当前服务器。但在我看来,这是一种非常复杂的解决问题的方法。与其有一个你调用的模板,通过索引号查找要处理的元素,为什么不简单地使用匹配的模板呢:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"
              doctype-system="about:legacy-compat"
              encoding="UTF-8"
              indent="yes" />
  <xsl:template match="/">
    <html>
      <head>
        <title>Distribution POP Green Light</title>
        <link rel="stylesheet" href="../index_files/staleric.css" />
      </head>
      <body>
        <table class="staleric">
          <thead>
            <tr>
              <td>POP :</td><td><xsl:value-of select="pop/@name"/></td>
            </tr>
            <tr>
              <th>Server</th>
              <th>Status</th>
              <th>Stale RIC</th>
            </tr>
          </thead>
          <tbody>
            <!-- process all the servers -->
            <xsl:apply-templates select="pop/server" />
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="server">
    <tr>
      <td><xsl:value-of select="name"/></td>
      <td>
        <xsl:choose>
          <xsl:when test="status = 'red'">
            <img src="../images/red.png"></img>
          </xsl:when>
          <xsl:otherwise>
            <img src="../images/green.png"></img>
          </xsl:otherwise>
        </xsl:choose>
      </td>
      <td>
        <!-- process all the ric elements for this server (if any) -->
        <xsl:apply-templates select="staleric/ric" />
      </td>
    </tr>
  </xsl:template>
  <xsl:template match="ric">
    <xsl:text>Service : </xsl:text>
    <xsl:value-of select ="@service"/>
    <xsl:text> RIC : </xsl:text>
    <xsl:value-of select ="@name"/>
    <br/>
  </xsl:template>
</xsl:stylesheet>

1:从技术上讲,例如,对于$value=1,select将拉出一个由整个文档中的所有ric元素组成的集合,这些元素是其各自父级中的第一个ric,而XSLT1.0中的value-of a多节点集合被定义为该集合中按文档顺序的第一个节点的值,随后的节点被完全忽略

我相信这是:

Service : <xsl:value-of select ="//ric[$value]/@service"/>
RIC : <xsl:value-of select ="//ric[$value]/@name"/>

需要:

Service : <xsl:value-of select ="staleric/ric[$value]/@service"/>
RIC : <xsl:value-of select ="staleric/ric[$value]/@name"/>

相关内容

  • 没有找到相关文章