Xml 减少XSLT1.0中的重复表达式
我有以下XML(简化):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])"/
测试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