减少XSLT 1.0中的重复表达式

时间:2010-06-22 13:27:54

标签: xml xslt

我有以下XML(简化):

<?xml version="1.0" encoding="utf-8"?>
<TestCases>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type2</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Passed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
</TestCases>

我有兴趣创建一个表,根据类型计算传递/失败测试用例的数量,如下所示:

通过(Type1):1 失败(Type1):1 通过(其他类型):0 失败(其他类型):1

为此,我写了以下查询:

<xsl:value-of select="count(//TestCase[Result = 'Passed' and count(Properties/TestType='Type1')>0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Failed' and count(Properties/TestType='Type1')>0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Passed' and count(Properties/TestType='Type1')=0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Failed' and count(Properties/TestType='Type1')=0])"/>

正如你所看到的,有很多代码重复,如果我可以保存一些代码,那将会很棒。我知道在XSL 2.0中我可以使用它的用户函数,但是我应该在XSL 1.0中做什么?您是否看到可以看到的任何选项来优化重复表达式?

P.S注意,这是对真实的简化,虽然这里的表达似乎不长,但在真实的代码中,它的篇幅相当长,因此需要非常真实。

谢谢!

2 个答案:

答案 0 :(得分:3)

尝试:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:key name="byType" match="Properties/Type" use="."/> 

    <xsl:template match="text()" /> 

    <xsl:template match="Type[count(.|key('byType',.)[1])=1]"> 
        <xsl:value-of select="concat(' Passed (',.,'): ',
                                      count(key('byType',.)[../../Result='Passed']),
                                      ' Failed (',.,'): ',
                                      count(key('byType',.)[../../Result='Failed']))" /> 
    </xsl:template>  

</xsl:stylesheet> 

你得到:

 Passed (Type1): 1 Failed (Type1): 1 Passed (Type2): 0 Failed (Type2): 1

修改:更简洁。

答案 1 :(得分:1)

除了优秀的解决方案bu @Alejandro使用Muenchian方法进行分组之外,这里还有一个说明变量使用的方法

此转化:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vPassed"
      select="/*/*[Result = 'Passed']"/>

 <xsl:variable name="vFailed"
      select="/*/*[Result = 'Failed']"/>

 <xsl:template match="/">
  <xsl:value-of select=
   "concat('Passed (Type1): ',
           count($vPassed[Properties/Type='Type1']),
           ' Failed (Type1): ',
           count($vFailed[Properties/Type='Type1']),
           ' Passed (Other types): ',
           count($vPassed[not(Properties/Type='Type1')]),
           ' Failed (Other types): ',
           count($vFailed[not(Properties/Type='Type1')])
          )
   "/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<TestCases>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type2</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Passed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
</TestCases>

生成想要的正确结果

Passed (Type1): 1 Failed (Type1): 1 Passed (Other types): 0 Failed (Other types): 1