XSL:当路径作为参数提供时,缺少输出



我试图理解为什么当我将定义更改为使用具有相同值的参数时,我的代码会产生不同的结果,因为我想从xls中的其他位置调用模板,提供路径作为参数,这样代码就可以重用,而不是根据XML 中的位置进行定制

    <!--  Create SLA bar section  -->
    <xsl:template name="createBars">
       <xsl:param name="varPath"/>  <!-- Not used -->
       <xsl:param name="varNode"/>  <!-- Not used -->
       <table id="tblgraph" align="center" width="100" cellpadding="0" cellspacing="0" border="0">
         <tr style='width:100%'>
           <td align="left" width="100%" height="10" colspan="12">
             <table cellpadding="0" cellspacing="0" border="1" width="100%" style='color:black; font-weight:bold;'>
               <xsl:for-each select="/page/workgroups/workgroup/queue/currentshift/servicelevels">
                   <xsl:for-each select="servicelevel">
                     <xsl:variable name="keyValue">
                       <xsl:value-of select="key"/>
                     </xsl:variable>
                     <xsl:variable name="valueContent">
                       <xsl:value-of select="value"/>
                     </xsl:variable>                       
                     <tr>
                       <td>
                         <xsl:value-of select="$keyValue"/>
                       </td>
                       <td>
                         <xsl:value-of select="$valueContent"/>..
                       </td>
                     </tr>
                  </xsl:for-each>
               </xsl:for-each>
            </table>
          </td>
        </tr>
      </table>
    </xsl:template>

创建表的预期输出

0..20 |-。。20..30|-。。30..40|-。。40.50 |-。。50.60|-。。60..70|-。。70+|-。。

然而,当我更改代码以使用已在模板调用部分设置的传递参数时,替换

 <xsl:for-each select="/page/workgroups/workgroup/queue/currentshift/servicelevels">

带有

 <xsl:for-each select="msxsl:node-set($varPath)">

 <xsl:for-each select="servicelevel">

带有

 <xsl:for-each select="msxsl:node-set($varNode)">

结果是空的

结果:

。。

在调用配置文件中,参数设置如下:

  <!-- Set path and node for the information to be processed to build the bars -->
  <xsl:variable name="tempPath">
    <xsl:copy-of select="/page/workgroups/workgroup/queue/currentshift/servicelevels"/>
  </xsl:variable>
  <xsl:variable name="tempNode">
    <xsl:copy-of select="servicelevel"/>
  </xsl:variable>
            
  <!-- Call the template to build the bars -->
  <xsl:call-template name="createBars">
    <xsl:with-param name="varPath" select="$tempPath"/>
    <xsl:with-param name="varNode" select="$tempNode"/>
  </xsl:call-template>

如何指定表示路径的参数,如:
/page/workgroups/workgroup/queue/currentshift/servicelevelsservicelevel
可以修改为例如:
/page/workgroups/workgroup/queue/currentperiod/abandonedsabandoned

这一切都能够调用模板,根据统计信息中类似的条目创建条形值。

XML文件:

<?xml version="1.0"?>
<page id="7080959">
  <name>Test Ruud</name>
  <description/>
  <server>reg6699cic01</server>
  <created>2014/07/25 08:12:01 AM</created>
  <workgroups>
    <workgroup>
      <name>ITSD_APAC_Windows_Manila</name>
        <agents>2</agents>
          <queue>
           <longesttalktime>-</longesttalktime>
           <longestwaiting>-</longestwaiting>
           <currentperiod>
             <numberabandoned>0</numberabandoned>
             <periodlength>00:11:59</periodlength>
             <servicelevels>
               <servicelevel>
                 <key>0..20</key>
                 <value>98</value>
               </servicelevel>
               <servicelevel>
                 <key>20..30</key>
                 <value>100</value>
               </servicelevel>
             </servicelevels>
             <abandoneds>
               <abandoned>
                 <key>0..20</key>
                 <value>-</value>
               </abandoned>
               <abandoned>
                 <key>20..30</key>
                 <value>-</value>
               </abandoned>
             </abandoneds>
           </currentperiod>
           <currentshift>
             <numberabandoned>4</numberabandoned>
             <periodlength>21:11:59</periodlength>
             <servicelevels>
               <servicelevel>
                 <key>0..20</key>
                 <value>-</value>
               </servicelevel>
               <servicelevel>
                 <key>20..30</key>
                 <value>-</value>
               </servicelevel>
             </servicelevels>
             <abandoneds>
               <abandoned>
                 <key>0..20</key>
                 <value>1</value>
             </abandoned>
             <abandoned>
               <key>20..30</key>
               <value>-</value>
             </abandoned>
           </abandoneds>
         </currentshift>
       </queue>
     </workgroup>
   </workgroups>
 </page>

所以条形模板的目标是:

  • /page/workgroups/workgroup/queue/currentshift/servicelevels,具有用于ServiceLevel 的六个子节点

  • /page/workgroups/workgroup/queue/currentshift/abandoneds,具有用于abandoned 的六个子节点

  • /page/workgroups/workgroup/queue/currentperiod/servicelevel,具有用于servicelevel 的六个子节点

  • /page/workgroups/workgroup/queue/currentperiod/abandoneds,具有用于abandoned 的六个子节点

    每个节点都包含

  • Key

  • Value

期待您的回复

首先,我假设您获得空结果集的原因:您的具体问题源于您将空节点集传递给模板的第二个参数:

<xsl:variable name="tempNode">
  <xsl:copy-of select="servicelevel"/>
</xsl:variable>

XSLT处理器评估此表达式时,会尝试查找当前节点的所有<servicelevel>子级。最有可能的是,由于您使用第一个参数的完整路径,因此没有

<xsl:variable name="tempPath">
  <xsl:copy-of select="/page/workgroups/workgroup/queue/currentshift/servicelevels"/>
</xsl:variable>

向我们表明,定义变量的上下文可能是而不是/page/workgroups/workgroup/queue/currentshift/servicelevels

现在修复:根据XSLT判断,您尝试定义位于tempPath中的基节点集,然后在tempNode中提供的相对路径所给出的这些节点的子节点上循环。正如@michael.hor257k已经指出的那样,这在XSLT中不起作用(至少不是1.0或2.0),尽管实际上您传递的不是字符串而是一个空节点。

然而,在您的特定情况下,您可以通过消除内部循环来简化模板。这应该是可能的,因为在外循环中没有不在内循环中的功能。因此,不使用两个参数调用模板,只使用一个包含内部循环所有节点的参数:

<xsl:variable name="tempNode">
  <xsl:copy-of select="/page/workgroups/workgroup/queue/currentshift/servicelevels/servicelevel"/>
</xsl:variable>
<!-- Call the template to build the bars -->
<xsl:call-template name="createBars">
  <xsl:with-param name="varNode" select="$tempNode"/>
</xsl:call-template>

您简化模板如下:

<!--  Create SLA bar section  -->
<xsl:template name="createBars">
   <xsl:param name="varNode"/> 
   <table id="tblgraph" align="center" width="100" 
          cellpadding="0" cellspacing="0" border="0">
     <tr style='width:100%'>
       <td align="left" width="100%" height="10" colspan="12">
         <table cellpadding="0" cellspacing="0" border="1" 
                width="100%" style='color:black; font-weight:bold;'>
           <xsl:for-each select="msxsl:node-set($varNode)">
           ... add here the contents of the !inner! loop
           </xsl:for-each>
        </table>
      </td>
    </tr>
  </table>
</xsl:template>

这样就不需要评估相对路径了!

完整解决方案

以下XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:common="http://exslt.org/common"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:template match="/">
    <xsl:variable name="tempPath">
      <xsl:copy-of select="/page/workgroups/workgroup/queue/currentshift/servicelevels/servicelevel"/>
    </xsl:variable>
    <tables>
      <xsl:call-template name="createBars">
        <xsl:with-param name="varNode" select="$tempPath"/>
      </xsl:call-template>
      <xsl:call-template name="createBars">
        <xsl:with-param name="varNode" select="/page/workgroups/workgroup/queue/currentperiod/servicelevels/servicelevel"/>
      </xsl:call-template>
      <xsl:call-template name="createBars">
        <xsl:with-param name="varNode" select="/page/workgroups/workgroup/queue/currentperiod/abandoneds/abandoned"/>
      </xsl:call-template>
    </tables>
  </xsl:template>
  <xsl:template name="createBars">
       <xsl:param name="varNode"/>  
       <table id="tblgraph" align="center" width="100" cellpadding="0" cellspacing="0" border="0">
         <tr style='width:100%'>
           <td align="left" width="100%" height="10" colspan="12">
             <table cellpadding="0" cellspacing="0" border="1" width="100%" style='color:black; font-weight:bold;'>
               <xsl:for-each select="common:node-set($varNode)">
                 <tr>
                   <td><xsl:value-of select="key"/></td>
                   <td><xsl:value-of select="value"/>..</td>
                 </tr>
               </xsl:for-each>
             </table>
           </td>
         </tr>
       </table>
    </xsl:template>
</xsl:stylesheet>

从问题中的XML生成以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<tables xmlns:common="http://exslt.org/common">
  <table id="tblgraph" align="center" width="100" cellpadding="0" cellspacing="0" border="0">
    <tr style="width:100%">
      <td align="left" width="100%" height="10" colspan="12">
        <table cellpadding="0" cellspacing="0" border="1" width="100%" style="color:black; font-weight:bold;">
          <tr>
            <td/>
            <td>..</td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
  <table id="tblgraph" align="center" width="100" cellpadding="0" cellspacing="0" border="0">
    <tr style="width:100%">
      <td align="left" width="100%" height="10" colspan="12">
        <table cellpadding="0" cellspacing="0" border="1" width="100%" style="color:black; font-weight:bold;">
          <tr>
            <td>0..20</td>
            <td>98..</td>
          </tr>
          <tr>
            <td>20..30</td>
            <td>100..</td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
  <table id="tblgraph" align="center" width="100" cellpadding="0" cellspacing="0" border="0">
    <tr style="width:100%">
      <td align="left" width="100%" height="10" colspan="12">
        <table cellpadding="0" cellspacing="0" border="1" width="100%" style="color:black; font-weight:bold;">
          <tr>
            <td>0..20</td>
            <td>-..</td>
          </tr>
          <tr>
            <td>20..30</td>
            <td>-..</td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</tables>

注:

  • 首先将XPath表达式分配给变量,然后将其作为参数传递,这在第一个模板调用中是不起作用的
  • 我无法测试微软版本的node-set(),但xsltproc中提供的common:node-set()函数有望显示出相同的行为
  • 添加<tables></tables>标记只是为了创建一个有效的目标XML文件
  • 通过去除局部变量,<td>标签的输出被稍微简化

相关内容

  • 没有找到相关文章

最新更新