Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 减少XSLT1.0中的重复表达式_Xml_Xslt - Fatal编程技术网

Xml 减少XSLT1.0中的重复表达式

Xml 减少XSLT1.0中的重复表达式,xml,xslt,Xml,Xslt,我有以下XML(简化): 测试1 失败 类型1 测试1 失败 类型2 测试1 通过 类型1 我想创建一个表,根据测试用例的类型统计通过/失败的测试用例的数量,如下所示: 通过(类型1):1 失败(类型1):1 已通过(其他类型):0 失败(其他类型):1 为此,我编写了以下查询: <xsl:value-of select="count(//TestCase[Result = 'Passed' and count(Properties/TestType='Type1')>0])"/

我有以下XML(简化):


测试1
失败
类型1
测试1
失败
类型2
测试1
通过
类型1
我想创建一个表,根据测试用例的类型统计通过/失败的测试用例的数量,如下所示:

通过(类型1):1 失败(类型1):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])"/>

正如您所看到的,有很多代码重复,如果我能保存一些代码,那就太好了。我知道在XSL2.0中我可以使用用户函数,但是在XSL1.0中我应该怎么做呢?您是否看到可以优化重复表达式的任何选项

注意,这是对实数的简化,虽然表达式在这里看起来并不长,但在实数代码中它相当长,所以需要的是实数

谢谢

试试看:

<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> 

编辑:不太详细。

除了使用Muenchian方法分组的优秀解决方案bu@Alejandro外,下面是一个说明变量使用的示例

<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
此转换:

<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>

哇,你认为你知道一些XSLT,然后你看到了你以前从未见过的东西。我会试试看,然后再打给你。谢谢,很有趣。我不认为我能用表情做这样的事情。如果它们确实只是一个字符串,并且可以进行这样的操作,那么我是否也可以使用声明变量并在表达式中使用它?@VitalyB:是的。可以在xpath表达式中使用变量和参数,但不能在模式中使用。示例:
好问题(+1)。有关使用
定义变量的解决方案,请参见我的答案。有趣!2个问题:1)为什么只定义通过/失败的表达式?还为类型定义变量怎么样?例如:
然后你可以写:
count($vPassed[$vType1])
2)我对你的语法感到困惑:
为什么在前面添加了/*/*?@VitalyB:1)你的建议:
count($vPassed[$vType1])
如果
$vType1
非空,总是选择
$vPassed
中的所有节点。您需要学习XPath。这就是我没有选择那条路线的原因。对于您的问题2)——再次学习XPath——特别是阅读上下文节点、绝对表达式和相对表达式。
<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