我试着理解为什么在我的代码中更改定义以使用具有相同值的参数时产生不同的结果,因为我想从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/servicelevels
和servicelevel
可以修改为例如:
/page/workgroups/workgroup/queue/currentperiod/abandoneds
和abandoned
这一切都能够调用模板,根据统计信息中的相似条目创建条形值。
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
期待您的回复
答案 0 :(得分:0)
首先,我假设您获取一个空结果集:您的具体问题来自于您将空节点集传递给模板的第二个参数:
<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>
注意:
node-set()
的Microsoft版本,但common:node-set()
中提供的xsltproc
函数有望显示相同的行为。<tables></tables>
标记以创建有效的目标XML文件。<td>
标签的输出略有简化。