我正在尝试解析从 googletest 输出的 xml 文件,以在 html 页面中以漂亮的方式显示结果。我对此有相当的了解并且有一个可行的解决方案。只剩下一件事要做。 目前每个类都有一个标题,每个函数+测试都显示在下面,我正在寻找一种从 xml 属性中提取函数名称以将其作为自己的子标题的方法。下面的例子
当前输出
类名
函数名_测试名
functionName_test2Name
function2Name_testName
期望的输出
类名
函数名
测试名称
测试名称
函数名
测试名称
待解析的 XML
<testsuite name="testPacketProcessor" tests="27" failures="0" disabled="0" errors="0" time="36.875">
<testcase name="testInitialise_IpNotSet" status="run" time="0" classname="testPacketProcessor" />
<testcase name="testInitialise_GoodIp" status="run" time="2.046" classname="testPacketProcessor" />
<testcase name="testInitialise_BadIp" status="run" time="0.032" classname="testPacketProcessor" />
</testsuite>
当前实现的 XSL
<xsl:for-each select="testsuites/testsuite">
<div class="testHeading">
<span><xsl:value-of select="substring-after(@name,'test')"/></span>
</div>
<xsl:for-each select="testcase">
<div class="testReport">
<xsl:if test="not(starts-with(@name,'DISABLED'))"><xsl:value-of select="substring-after(@name,'test')"/></xsl:if>
<xsl:if test="starts-with(@name,'DISABLED')"><xsl:value-of select="substring-after(@name,'DISABLED_test')"/></xsl:if>
<xsl:text> - </xsl:text>
<xsl:if test="starts-with(@status,'run')">
<xsl:if test="failure"><xsl:text>Fail</xsl:text></xsl:if>
<xsl:if test= "not(failure)"><xsl:text>Pass</xsl:text></xsl:if>
</xsl:if>
<xsl:if test="starts-with(@status,'not')"><xsl:text>Disabled</xsl:text></xsl:if>
</div>
</xsl:for-each>
</xsl:for-each>
以上面的 xml 为例,我希望在数据包处理器标题下有一个“初始化”的副标题,每个测试都记录在副标题下
任何有关解决此问题的最佳方法的建议都将不胜感激。我查看了 xsl 变量,但无法理解如何处理无法更改值的问题。还阅读了一些有关 xsl 模板和递归的内容,但我不确定在这种情况下如何工作。
提前致谢
小狗
最佳答案
此转换为每个测试用例生成副标题和名称:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="testcase">
Subheading: <xsl:value-of select=
"substring-before(substring-after(@name, 'test'),
'_'
)
"/>
Name: <xsl:value-of select="substring-after(@name, '_')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<testsuites>
<testsuite name="testPacketProcessor" tests="27" failures="0" disabled="0" errors="0" time="36.875">
<testcase name="testInitialise_IpNotSet" status="run" time="0" classname="testPacketProcessor" />
<testcase name="testInitialise_GoodIp" status="run" time="2.046" classname="testPacketProcessor" />
<testcase name="testInitialise_BadIp" status="run" time="0.032" classname="testPacketProcessor" />
</testsuite>
</testsuites>
产生了想要的、正确的结果:
Subheading: Initialise
Name: IpNotSet
Subheading: Initialise
Name: GoodIp
Subheading: Initialise
Name: BadIp
说明:使用标准的 XPath 函数 substring-before()
和 substring-after()
编辑:在评论中,OP 澄清说他想按功能分组(厌倦了糟糕的问题?):
此转换执行所需的分组:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kTestsByFunction" match="testcase"
use="substring-before(substring-after(@name, 'test'),
'_'
)"
/>
<xsl:template match=
"testcase
[generate-id()
=
generate-id(key('kTestsByFunction',
substring-before(substring-after(@name, 'test'),
'_'
)
)[1]
)
]
">
Subheading:
<xsl:value-of select=
"substring-before(substring-after(@name, 'test'),
'_'
)
"/>
<xsl:for-each select=
"key('kTestsByFunction',
substring-before(substring-after(@name, 'test'),
'_'
)
)
">
Name:
<xsl:value-of select="substring-after(@name, '_')"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
并产生想要的结果:
Subheading:
Initialise
Name:
IpNotSet
Name:
GoodIp
Name:
BadIp
关于html - 使用xsl解析xml输出,使用变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5635297/