2012-06-04 50 views
0

我是全新编写xslt代码的新手。我想让xsl代码查看xml文件中的每个节点/属性,并搜索'__(string)'并计算'result = success/failed'。我在这个网站上找到了一个线程来帮助我一点: How do you do wildcard matches with XSLT?
我找到了我的xsl代码来查找字符串匹配。但后来我的问题是,我不知道如何编写代码来计算成功和给定的字符串匹配失败?我希望为输出看起来是这样的:XSLT:如何计算属性,使用字符串匹配找到

 **(Casename)** | **(total success)** | **(total failed)** 
    __(stringmatch1)|   2   |  0 
    __(stringmatch2)|   0   |  2 

下面是XML文件的样本:

<report> 
    <programtest user="testuser"> 
      <programtest software="test"> 
       <programtest testname="SW log"> 
       </programtest> 
       <programtest testname="HW log"> 
       </programtest> 
       <programtest testname="loop_program_test"> 
        <programtest casename="test" iteration="1" result="success"> 
        <programtest casename="__temp1" type="specifictestcase" result="success" > 
         </programtest> 
         <programtest casename="__temp2" type="specifictestcase" result="failed" > 
         </programtest> 
        </programtest> 
        <programtest casename="test" iteration="2" result="success"> 
         <programtest casename="__temp1" type="specifictestcase" result="success" > 
         </programtest> 
         <programtest casename="__temp2" type="specifictestcase" result="failed" > 
         </programtest> 
        </programtest> 
       </programtest> 
      </programtest> 
    </programtest> 
</report> 

任何帮助表示赞赏! :-)

回答

1

我认为这是一个分组问题。您需要通过@casename属性为每个特定的programtest元素对结果进行分组。在XSLT2.0,你会被XSL的方式做到这一点:对,每个组元素

<xsl:for-each-group select=".//programtest[@type='specifictestcase']" group-by="@casename"> 

然后,对于每个组,你会得到成功的次数,像这样

<xsl:value-of select="count(current-group()[@result='succes'])"/> 

(NB有可能在你的XML一个错字,因为不是它应该是“成功”,而不是“更迭”?)

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:template match="/report"> 
     <table> 
     <tr> 
      <th>**(Casename)**</th> 
      <th>**(total success)**</th> 
      <th>**(total failed)**</th> 
     </tr> 
     <xsl:for-each-group select=".//programtest[@type='specifictestcase']" group-by="@casename"> 
      <tr> 
       <td> 
        <xsl:value-of select="current-grouping-key()"/> 
       </td> 
       <td> 
        <xsl:value-of select="count(current-group()[@result='succes'])"/> 
       </td> 
       <td> 
        <xsl:value-of select="count(current-group()[@result='failed'])"/> 
       </td> 
      </tr> 
     </xsl:for-each-group> 
     </table> 
    </xsl:template> 
</xsl:stylesheet> 

当适用于您的示例XML,下面是输出

<table> 
    <tr> 
     <th>**(Casename)**</th> 
     <th>**(total success)**</th> 
     <th>**(total failed)**</th> 
    </tr> 
    <tr> 
     <td>__temp1</td> 
     <td>2</td> 
     <td>0</td> 
    </tr> 
    <tr> 
     <td>__temp2</td> 
     <td>0</td> 
     <td>2</td> 
    </tr> 
</table> 
+0

这听起来很不错。是的,你的权利是错误的。但尝试这样做,给我错误,我的xml编辑器不能识别“for-each-group”扩展名。我使用VS2010作为xml编辑器,并确保使用XSLT v 2.0即时消息。 – Joks

+0

噢,好的。它有助于使用氧气xml编辑器。 :) – Joks

+0

如果您使用Visual Studio,那么您可能需要XSLT v1.0解决方案,因为Microsoft的XML处理器不支持2.0。 –

1

好做

<xsl:variable name="matchedElements" select="//*[starts-with(@casename, '__')]"/> 
<xsl:variable name="unmatchedElements" select="//*[not(starts-with(@casename, '__'))]"/> 

,你可以找到的元素,然后可以,如果需要例如你输出的数字

<table> 
    <thead> 
    <tr> 
    <th>matched</th> 
    <th>not matched</th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr> 
     <td><xsl:value-of select="count($matchedElements)"/></td> 
     <td><xsl:value-of select="count($unmatchedElements)"/></td> 
    </tr> 
    </tbody> 
</table> 

这有帮助吗?

我只是使用starts-with(@casename, '__'),根据您的需要,您当然可以使用其他测试,如@casename = '__temp1'matches(@casename, 'some regular expression pattern here')

+0

谢谢,这是一个良好的开端。尽管如此,我的下一个问题是,要说明'__(stringmatches)'之间的区别。 – Joks