gpt4 book ai didi

xml - 需要 XSL 文件将内部 xml 测试格式转换为 Junit 格式(jenkins 的 xUnit 插件)

转载 作者:数据小太阳 更新时间:2023-10-29 02:05:34 26 4
gpt4 key购买 nike

我正在尝试编写一个 XSL 以将我的 XML 转换为 jenkins 采用的 JUNIT 格式(见下文)

我的 xml 看起来像这样:(我有几个“类”,如“数据中心”或“网络”)

<tests>
<Datacenters>
<test_name>Create NFS Data Center</test_name>
<end_time>2011-06-13 01:22:55</end_time>
<iter_num>1</iter_num>
<start_time>2011-06-13 01:22:52</start_time>
<status>Pass</status>
</Datacenters>
<Datacenters>
<test_name>Create NFS Data Center</test_name>
<end_time>2011-06-13 01:22:55</end_time>
<iter_num>1</iter_num>
<start_time>2011-06-13 01:22:52</start_time>
<status>Pass</status>
</Datacenters>
<Network>
<test_name>Network test 1</test_name>
<end_time>2011-06-13 01:22:57</end_time>
<iter_num>1</iter_num>
<start_time>2011-06-13 01:22:52</start_time>
<status>Pass</status>
</Network>
.....
</tests>

我从 WebUI 插件中获取了一个 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>

<! -- need to change /Datacenters to something else so it will work on all nodes -->
<xsl:variable name="buildName" select="//tests/Datacenters/test_name"/>
<xsl:variable name="numOfTests" select="count(//tests/Datacenters/iter_num)"/>
<xsl:variable name="numOfFail" select="count(//tests/Datacenters/status [.= 'Fail'])" />
<xsl:variable name="numberSkip" select="count(//tests/Datacenters/status [.!='Pass' and .!='Fail'])" />

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

<xsl:for-each select="//rest/Datacenters">
<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"/>
<!--<xsl:variable name="className" select="Data"/> -->
<testcase classname="Datacenters"
name="{$testName}"
time="{$duration_hours*3600 + $duration_minutes*60 + $duration_seconds }">

<xsl:if test="contains($outcome, 'Fail')">
<failure>
test_parameters: <xsl:value-of select="$test_parameters" />
test_positive: <xsl:value-of select="$test_positive" />
</failure>
</xsl:if>
</testcase>
</xsl:for-each>

</testsuite>
</testsuites>
</xsl:template>
</xsl:stylesheet>

我想要实现的是这个 xml:

  <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="Datacenters" tests="2" time="4" failures="0" errors="0" skipped="0">
<testcase classname="Datacenters" name="Create NFS Data Center" time="3"/>
<testcase classname="Datacenters" name="Create ISCSI Data Center" time="1"/>
</testsuite>
<testsuite name="Network" tests="1" time="5" failures="0" errors="0" skipped="0">
<testcase classname="Datacenters" name="Network test 1" time="5"/>
</testsuite>
</testsuites>

但我不知道如何迭代所有“类”,所以我希望它展示所有现有的 <tests> 的子项,而不是硬编码“数据中心”

最佳答案

我只想回答模板中的评论(您的代码可能需要调试和重构):

   <!-- need to change /Datacenters to something 
else so it will work on all nodes -->

为了避免硬编码:

1) 像这样替换 XPaths:

//tests/Datacenters/test_name

使用 //tests/*/test_name

2)修正迭代(完全错误),应该是:

<xsl:for-each select="//tests/Datacenters">

你想要:

 <xsl:for-each select="//tests/*">

3) 最后,做替换:

 <testcase classname="Datacenters">

 <testcase classname="{local-name(.)}">

评论后编辑

我将使用简化的输出来回答,只是为了向您展示分组在 XSLT 2.0 中的工作方式。希望这个答案对你来说是可以接受的,你的实际模板在这里有点难以测试:

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

<xsl:output indent="yes"/>

<xsl:template match="tests">
<testsuites>
<xsl:for-each-group select="*" group-by="local-name()">
<testsuite name="{current-grouping-key()}">
<xsl:for-each select="current-group()">
<testcase classname="{current-grouping-key()}"/>
</xsl:for-each>
</testsuite>
</xsl:for-each-group>
</testsuites>
</xsl:template>

</xsl:stylesheet>

应用于您问题中提供的输入样本,产生:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="Datacenters">
<testcase classname="Datacenters"/>
<testcase classname="Datacenters"/>
</testsuite>
<testsuite name="Network">
<testcase classname="Network"/>
</testsuite>
</testsuites>

关于xml - 需要 XSL 文件将内部 xml 测试格式转换为 Junit 格式(jenkins 的 xUnit 插件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6345737/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com