xslt - 如何在 xslt 中设置标志/变量以再次输入(与转换为 Junit 格式有关)

标签 xslt variables junit params

我正在通过 xslt 读取外部日志文件,我想找到某一行。
一旦我找到它,我想打印所有的行,直到我打到另一行。
我需要为一个非常大的日志文件重复执行此操作。
每次迭代都有一个唯一的 id,日志文件通过以下方式分隔相关信息
“迭代次数:X”直到“迭代次数X+1”(或EOF)。

这是我的 xsl:(相关代码在故障标签中)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" indent="yes" />    
    <xsl:template match="/">
        <testsuites>        
            <xsl:variable name="buildName" select="//rest/*/test_name"/>    
            <xsl:variable name="numberOfTests" select="count(//rest/*/iter_num)"/>
            <xsl:variable name="numberOfFailures" select="count(//rest/*/status [.= 'Fail'])" />    
            <xsl:variable name="numberSkipped" select="count(//rest/*/status [.!='Pass' and .!='Fail'])" /> 
            <xsl:variable name="logfile" select="//rest/@logfile" />    
            <xsl:variable name="testfile" select="//rest/@testFile" />

            <testsuite name="QE AUTOMATION TESTS"
                tests="{$numberOfTests}" time="0"
                failures="{$numberOfFailures}"  errors="0"
                skipped="{$numberSkipped}">

                <xsl:for-each select="//rest/*">
                    <xsl:variable name="testName" select="test_name"/>
                    <xsl:variable name="executionId" select="iter_num"/>
                    <xsl:variable name="start_time" select="fn:replace(start_time,' ','T')" />
                    <xsl:variable name="end_time" select="fn:replace(end_time,' ','T')"/>
                    <xsl:variable name="test_parameters" select="test_parameters"/>
                    <xsl:variable name="test_positive" select="test_positive"/>
                    <xsl:variable name="time_diff" select="xs:dateTime($end_time)-xs:dateTime($start_time)"/>
                    <xsl:variable name="duration_seconds" select="seconds-from-duration($time_diff)"/>
                    <xsl:variable name="duration_minutes" select="minutes-from-duration($time_diff)"/>  
                    <xsl:variable name="duration_hours" select="hours-from-duration($time_diff)"/>      
                    <xsl:variable name="outcome" select="status"/>  
                    <xsl:variable name="message" select="$buildName"/>  
                                <testcase classname="qe-tests.{local-name(.)}"
                                    name="{$testName}"
                                    time="{$duration_hours*3600 + $duration_minutes*60 + $duration_seconds }">
<xsl:if test="contains($outcome, 'Fail')"> 
    <failure>
        <xsl:param name="executionEnd" select="$executionId +1"/>
        <xsl:variable name="postIterX" select="tokenize(.,concat('Iteration number: ',$executionId,'\r?\n'),'m')[2]"/>
        <xsl:variable name="inIterX" select="tokenize($postIterX, concat('\r?\n.*Iteration number: ',$executionEnd,'\r?\n?'),'m')[1]"/>
        <xsl:value-of select="$inIterX"/>  
    </failure>
</xsl:if>
                            </testcase>
                </xsl:for-each>
            </testsuite>
        </testsuites>
    </xsl:template>
</xsl:stylesheet>

我更新了代码以使用@empo 解决方案,但以这种方式使用 xsl:param 时出现错误。

我拥有的日志文件是这样的(这是一个简化的片段)
(在本例中,从“迭代 70”行开始并在迭代 71 行停止)
2011-06-15 15:38:07,126 - networks - INFO - Compared entities are equal
2011-06-15 15:38:07,152 - rest-Main - INFO - Test status for iteration 60 Pass
2011-06-15 15:38:07,187 - rest-Main - INFO - Test name: add Network To Cluster
2011-06-15 15:38:07,192 - rest-Main - INFO - Iteration number: 70
2011-06-15 15:38:07,187 - rest-Main - INFO - Test action: addNetworkToCluster
2011-06-15 15:38:07,188 - rest-Main - INFO - Run test: yes
2011-06-15 15:38:07,188 - rest-Main - INFO - Test positive: TRUE
2011-06-15 15:38:07,152 - rest-Main - INFO - Test status for iteration 70 Fail
2011-06-15 15:38:07,192 - rest-Main - INFO - Iteration number: 71
2011-06-15 15:38:07,188 - rest-Main - INFO - Test positive: DDDDD
 2011-06-15 15:38:07,188 - rest-Main - INFO - Run test: yes
2011-06-15 15:38:07,188 - rest-Main - INFO - Test positive: TRUE

* EOF

所需的 xml 输出如下所示:(仅在失败时才会显示详细输出)
<?xml version="1.0" encoding="UTF-8"?>
<testsuites xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <testsuite name="QE AUTOMATION TESTS" tests="2" time="0" failures="1" errors="0" skipped="0">
        <testcase classname="qe-tests.Network" name="Add Network to Cluster="3">
            <failure>
2011-06-15 15:38:05,674 - rest-Main - INFO - Iteration number: 70
2011-06-15 15:38:05,674 - rest-Main - INFO - Running function: networks.addNetworkToCluster
2011-06-15 15:38:05,675 - rest-Main - INFO - Running command: testStatus=addNetworkToCluster('TRUE',network='testrest1',cluster='RestCluster1')
2011-06-15 15:38:05,675 - networks - DEBUG - GET request content is --  url:http://localhost:8080/rhevm-api/networks 
2011-06-15 15:38:05,887 - networks - DEBUG - Response body for GET request is: &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
2011-06-15 15:38:07,188 - rest-Main - INFO - Run test: yes
2011-06-15 15:38:07,188 - rest-Main - INFO - Test positive: TRUE
</failure>
        </testcase>
        <testcase classname="qe-tests.network" name="Add network to iscsi" time="1"/>
    </testsuite>
</testsuites>

原始 xml 看起来像这样:(片段)
“网络”只是一个可能的 child (例如,还有更像“数据中心”)
<?xml version="1.0" encoding="UTF-8"?>
<rest logfile="log.txt" testFile="REST_API.ods">
    <Network>
        <test_parameters>name='RestDataCenter2',storage_type='iscsi',version='3.0'</test_parameters>
        <test_name>Add Network to cluster</test_name>
        <end_time>2011-06-13 01:22:56</end_time>
        <iter_num>70</iter_num>
        <test_positive>TRUE</test_positive>
        <tcms_test_case/>
        <start_time>2011-06-13 01:22:55</start_time>
        <status>Fail</status>
    </Network>
    <Network>
        <test_parameters>name='RestDataCenter2',storage_type='iscsi',version='3.0'</test_parameters>
        <test_name>Add network to iscsi</test_name>
        <end_time>2011-06-13 01:22:56</end_time>
        <iter_num>71</iter_num>
        <test_positive>TRUE</test_positive>
        <tcms_test_case/>
        <start_time>2011-06-13 01:22:55</start_time>
        <status>Pass</status>
    </Network>
</rest>

最佳答案

我尝试使用 for-each-group(或者甚至使用键的 Muenchian 分组)来解决这个问题,但失败了,因为人口不包含节点,因此不允许进行如此多的有用操作。

模拟“正常编码”(即程序)循环的蛮力方法是使用递归。但是要做到这一点,您需要能够使用参数。然后,您可以通过定义一个 bool 参数来“定义一个 bool 标志”,并在您想要更改它时为其传递一个不同的值。或者更好的是,当您想停止打印行时,不要递归。

这是样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="2.0">
   <!-- $executionId is defined before and read from the xml, but for convenience: -->
   <xsl:variable name="executionId" select="'70'"/>
   <xsl:variable name="iter_line" select="concat('Iteration number: ',$executionId)"/>
   <xsl:variable name="logfile" select="'logfile.txt'" />
   <xsl:template match="/">
      <xsl:variable name="lines" select="tokenize(unparsed-text($logfile), '\r?\n')" />
      <xsl:call-template name="search-for-start">
         <xsl:with-param name="remaining-lines" select="$lines"/>
      </xsl:call-template>
   </xsl:template>

   <!-- skip lines until we find one that matches the start pattern -->
   <xsl:template name="search-for-start">
      <xsl:param name="remaining-lines" select="()"/>
      <xsl:choose>
         <xsl:when test="contains($remaining-lines[1], $iter_line)">
            <xsl:value-of select="$remaining-lines[1]"/>
            <xsl:text>&#x0a;</xsl:text>
            <xsl:call-template name="output-lines">
               <xsl:with-param name="remaining-lines" select="$remaining-lines[position() > 1]"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:call-template name="search-for-start">
               <xsl:with-param name="remaining-lines" select="$remaining-lines[position() > 1]"/>
            </xsl:call-template>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <!-- output the given lines, up to the next 'Iteration number: ' -->
   <xsl:template name="output-lines">
      <xsl:param name="remaining-lines"/>
      <xsl:choose>
         <!-- If so, we're done. -->
         <xsl:when test="contains($remaining-lines[1], 'Iteration number: ')" />
         <xsl:otherwise>
            <xsl:value-of select="$remaining-lines[1]"/>
            <xsl:text>&#x0a;</xsl:text>
            <xsl:call-template name="output-lines">
               <xsl:with-param name="remaining-lines" select="$remaining-lines[position() > 1]"/>
            </xsl:call-template>            
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

其中,在您的示例输出上进行测试,给出:(在序言之后)
2011-06-15 15:38:07,192 - rest-Main - INFO - Iteration number: 70
2011-06-15 15:38:07,187 - rest-Main - INFO - Test action: attachHostNic
2011-06-15 15:38:07,188 - rest-Main - INFO - Run test: yes
2011-06-15 15:38:07,188 - rest-Main - INFO - Test positive: TRUE

我相信这是所需的输出。

这似乎不是一个非常优雅的解决方案,但是当要分组的项目不是节点时,我不知道该怎么做。其他人有想法吗?

关于xslt - 如何在 xslt 中设置标志/变量以再次输入(与转换为 Junit 格式有关),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6366241/

相关文章:

java - 测试运行程序 JUnit5 未找到测试

unit-testing - 如何对此进行单元测试?

xml - XSLT 用于将原始 XML 插入 HTML 代码标记

xml - 从 xml 文档中获取不同的命名空间

xml - 添加 XSD 时 XSLT 转换失败

R 使用变量的值作为数据框列名

string - 两个变量作为单元格引用

xslt - Diazo - 有条件地向主题元素添加类

python - 如何将潜在变量输入 TensorFlow 图中?

java - '非法状态异常 : missing behavior definition for preceeding method call' even though behavior is defined