在xslt中的所有var上循环

时间:2011-01-26 09:55:27

标签: xslt variables foreach

我的Xslt语法有一些问题,我的样式表:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/">
<xsl:output method="xml" indent="yes"/>


<xsl:template match="/">

<root>

<xsl:for-each select="for $x in(collection('file:///Users/admin/Documents/xmlSoapUi/?select=*.xml;recurse=yes'))return saxon:discard-document($x)//testsuite"> 
 <ident>
    <xsl:value-of select="base-uri()"/>

 <xsl:if test="matches(base-uri(),'Catalog')">

    <xsl:call-template name="summaryCatalog"/>
</xsl:if>
<xsl:if test="matches(base-uri(),'Status')">
    <xsl:call-template name="summaryStatus"/>
</xsl:if>
<xsl:if test="matches(base-uri(),'Alarm')">
<xsl:call-template name="summaryAlarm"/>
</xsl:if>
 </ident>
</xsl:for-each>

</root> 

</xsl:template>

<xsl:template name="summaryCatalog">
    <xsl:variable name="avgAddFile" select="avg(testcase[@name='addFile']/@time)"/>
    <xsl:variable name="avgGetFile" select="avg(testcase[@name='getFile']/@time)"/>
    <xsl:variable name="avgRemoveFile" select="avg(testcase[@name='removeFile']/@time)"/>
    <xsl:variable name="avgAddGroup" select="avg(testcase[@name='addGroup']/@time)"/>
    <xsl:variable name="avgGetGroup" select="avg(testcase[@name='getGroup']/@time)"/>
    <xsl:variable name="avgRemoveGroup" select="avg(testcase[@name='removeGroup']/@time)"/>
    <xsl:variable name="avgAddMedia" select="avg(testcase[@name='addMedia']/@time)"/>
    <xsl:variable name="avgGetMedia" select="avg(testcase[@name='getMedia']/@time)"/>
    <xsl:variable name="avgRemoveMedia" select="avg(testcase[@name='removeMedia']/@time)"/>
    <xsl:variable name="avgAddMediaComponent" select="avg(testcase[@name='addMediaComponent']/@time)"/>
    <xsl:variable name="avgGetMediaComponent" select="avg(testcase[@name='getMediaComponent']/@time)"/>
    <xsl:variable name="avgRemoveMediaComponent" select="avg(testcase[@name='removeMediaComponent']/@time)"/>
    <xsl:variable name="avgAddOpus" select="avg(testcase[@name='addOpus']/@time)"/>
    <xsl:variable name="avgGetOpus" select="avg(testcase[@name='getOpus']/@time)"/>
    <xsl:variable name="avgRemoveOpus" select="avg(testcase[@name='removeOpus']/@time)"/>
    <xsl:variable name="avgAddTrack" select="avg(testcase[@name='addTrack']/@time)"/>
    <xsl:variable name="avgGetTrack" select="avg(testcase[@name='getTrack']/@time)"/>
    <xsl:variable name="avgRemoveTrack" select="avg(testcase[@name='removeTrack']/@time)"/>

    <testChargeCatalog>
    <avgAddFile><xsl:value-of select="format-number($avgAddFile,'0.00000')"/></avgAddFile>
    <avgGetFile><xsl:value-of select="format-number($avgGetFile,'0.00000')"/></avgGetFile>
    <avgRemoveFile><xsl:value-of select="format-number($avgRemoveFile,'0.00000')"/>    </avgRemoveFile>
    <avgAddGroup><xsl:value-of select="format-number($avgAddGroup,'0.00000')"/></avgAddGroup>
    <avgGetGroup><xsl:value-of select="format-number($avgAddGroup,'0.00000')"/></avgGetGroup>
    <avgRemoveGroup><xsl:value-of select="format-number($avgAddGroup,'0.00000')"/></avgRemoveGroup>
    <avgAddMedia><xsl:value-of select="format-number($avgAddMedia,'0.00000')"/></avgAddMedia>
    <avgGetMedia><xsl:value-of select="format-number($avgAddMedia,'0.00000')"/></avgGetMedia>
    <avgRemoveMedia><xsl:value-of select="format-number($avgAddMedia,'0.00000')"/></avgRemoveMedia>
    <avgAddMediaComponent><xsl:value-of select="format-number($avgAddMediaComponent,'0.00000')"/></avgAddMediaComponent>
    <avgGetMediaComponent><xsl:value-of select="format-number($avgGetMediaComponent,'0.00000')"/></avgGetMediaComponent>
    <avgRemoveMediaComponent><xsl:value-of select="format-number($avgRemoveMediaComponent,'0.00000')"/></avgRemoveMediaComponent>
    <avgAddOpus><xsl:value-of select="format-number($avgAddOpus,'0.00000')"/></avgAddOpus>
    <avgGetOpus><xsl:value-of select="format-number($avgGetOpus,'0.00000')"/></avgGetOpus>
    <avgRemoveOpus><xsl:value-of select="format-number($avgRemoveOpus,'0.00000')"/></avgRemoveOpus>
    <avgAddTrack><xsl:value-of select="format-number($avgAddTrack,'0.00000')"/></avgAddTrack>
    <avgGetTrack><xsl:value-of select="format-number($avgGetTrack,'0.00000')"/></avgGetTrack>
    <avgRemoveTrack><xsl:value-of select="format-number($avgRemoveTrack,'0.00000')"/></avgRemoveTrack>
    </testChargeCatalog>
</xsl:template>
<xsl:template name="summaryStatus">
    <xsl:variable name="avgAddStatus" select="avg(testcase[@name='addStatus']/@time)"/>
    <xsl:variable name="avgGetStatus" select="avg(testcase[@name='getStatus']/@time)"/>
    <testChargeStatus>
    <avgAddStatus><xsl:value-of select="format-number($avgAddStatus,'0.00000')"/></avgAddStatus>
    <avgGetStatus><xsl:value-of select="format-number($avgGetStatus,'0.00000')"/></avgGetStatus>
    </testChargeStatus>
</xsl:template>
<xsl:template name="summaryAlarm">
<xsl:variable name="avgAddAlarm" select="avg(testcase[@name='addAlarm']/@time)"/>
<xsl:variable name="avgGetAlarm" select="avg(testcase[@name='getAlarm']/@time)"/>
<testChargeAlarm>
<avgAddAlarm><xsl:value-of select="format-number($avgAddAlarm,'0.00000')"/></avgAddAlarm>
<avgGetAlarm><xsl:value-of select="format-number($avgGetAlarm,'0.00000')"/></avgGetAlarm>
</testChargeAlarm>
</xsl:template>

我想要做的是创建一个<xsl:for-each select="AllVariables">的模板 然后将一些变换应用于变量的值。

我不知道是否有可能,因为我没有在网上看过任何例子。

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

您可以(使用XSLT 2.0)创建一个由多个值组成的变量,然后您可以使用for-each来处理该值序列。当然,您可以使用for-each或apply-templates创建可以进一步处理的节点的临时结果。所以这是你应该选择的方法,而不是声明十个变量,每个变量都有一个值,你需要创建一个具有十个原始值序列的变量,或者你需要创建一个包含XML节点的临时树的变量,那么你可以在临时树中的那些节点上使用apply-templates或for-each。

答案 1 :(得分:1)

您可以创建一个xsl:variable,它是xsl:variable / xsl:import层次结构中从主样式表模块开始的所有xsl:include的并集。

但是,你通常不会得到,你只会获得select属性(或变量的主体)中指定的表达式,但你不会由于以下主要原因,能够“获得价值”;

  1. 无法在XSLT / XPath(版本1.0和2.0)中动态评估任何XPath表达式。

  2. 即使可以进行动态评估(比如版本3.0),也无法重新创建表达式的动态上下文 - 例如,变量是本地定义的,并使用其他变量或参数或上下文相关函数,例如position()last()

答案 2 :(得分:1)

我不清楚为什么你不能这样做:

<testChargeCatalog>
   <xsl:for-each-group select="testcase" group-by="@name"> 
      <xsl:element name="avg{upper-case(
                                substring(
                                   current-grouping-key(),
                                   1,
                                   1
                                )
                             )
                            }{substring(current-grouping-key(),2)}">
         <xsl:value-of select="format-number(
                                  avg(current-group()/@time),
                                  '0.00000'
                               )"/>  
      </xsl:element>  
   <xsl:for-each-group>  
</testChargeCatalog>