XSL转换模板仅返回最后一个属性值

时间:2019-01-10 09:15:01

标签: java xml xslt groovy

您好,祝堆栈溢出社区新年快乐! 这是我第一次使用XSL将xml转换为另一种xml格式。 事情是我让整个事情都在工作(或者至少我以为我做了),但是缺点是它没有返回我期望的完全相同的输出。 所需的输入和输出如下: Input.xml

    <?xml version="1.0"?>
<TestExecutionSummary>
<ExecutionDate>12-okt-2018 15-43-46</ExecutionDate>
<ExecutedTestCases>3</ExecutedTestCases>
<PassedTestCases>2</PassedTestCases>
<FailedTestCases>1</FailedTestCases>
<TimeTaken>00:03:48</TimeTaken>
<Testcases>
        <TestCaseStatus name="TC001" status="PASS"/>
        <TestCaseStatus name="TC002" status="PASS"/>
        <TestCaseStatus name="TC003" status="FAIL"/>
</Testcases>
</TestExecutionSummary>

输出xml

<?xml version="1.0"?>
<testsuite time="548.000" tests="2" errors="0" skipped="0" failures="1">
<testcase classname="CITS" name="TC001"/>
<testcase classname="CITS" name="TC002"/>
<testcase classname="CITS" name="TC003"/>
<failure type="CITS test failure">unknown failure</failure>
</testsuite>

我的XSL模板如下:

    <?xml version="1.0" encoding="UTF-8"?>

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

<xsl:output encoding="utf-8" method="xml" version="1.0" indent="yes"/>

<xsl:template match="/">
    <testsuite>
    <xsl:attribute name="time"><xsl:value-of select="TestExecutionSummary/TimeTaken"/></xsl:attribute>
    <xsl:attribute name="tests"><xsl:value-of select="TestExecutionSummary/ExecutedTestCases"/></xsl:attribute>
    <xsl:attribute name="errors">0</xsl:attribute>
    <xsl:attribute name="skipped">0</xsl:attribute>
    <xsl:attribute name="failures"><xsl:value-of select="TestExecutionSummary/FailedTestCases"/></xsl:attribute>
                <testcase>
                <xsl:for-each select="TestExecutionSummary/Testcases/TestCaseStatus[@status]">
                    <xsl:attribute name="classname">CITS</xsl:attribute>
                    <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
                </xsl:for-each>
                </testcase>
                <failure><xsl:attribute name="type">CITS test failure</xsl:attribute>"unknown error"</failure>           
    </testsuite>
</xsl:template>

</xsl:stylesheet>

但是我看到的奇怪的是,这种转换总是把我作为结果返回并运行完整的测试列表。 “ xsl:for-each”应循环通过TestCaseStatus节点并列出我认为的“名称”属性。但是结果是这样的:

    <testsuite time="00:03:48"
           tests="3"
           errors="0"
           skipped="0"
           failures="1">
   <testcase classname="CITS" name="TC003"/>
   <failure type="CITS test failure">"unknown error"</failure>
</testsuite>

如您所见,我只获得测试名称TC003,而不是TC001和TC002,这就是为什么我想知道我在哪里做错了。在此期间,我尝试研究示例XSL模板和一些教程,但是在用户遇到此问题的任何论坛中都没有遇到任何情况。所以有人可以指出我在哪里做错了吗?预先感谢!

JFYI如果需要的话,我还可以发布如何使用XSL在Groovy中进行转换,但是当我在在线转换站点上尝试此输入和模板时,我认为效果很好。

2 个答案:

答案 0 :(得分:1)

您需要将<testcase>的创建移到xsl:for-each内部,而不是外部。否则,您将只创建一个<testcase>元素,然后尝试向该元素添加多个属性。 (如果您尝试将属性添加到已经具有该属性的元素中,则该属性将被替换)。

    <xsl:for-each select="TestExecutionSummary/Testcases/TestCaseStatus[@status]">
        <testcase>
            <xsl:attribute name="classname">CITS</xsl:attribute>
            <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
        </testcase>
    </xsl:for-each>

或者更好,做到这一点

    <xsl:for-each select="TestExecutionSummary/Testcases/TestCaseStatus[@status]">
        <testcase classname="CITS" name="{@name}"/>
    </xsl:for-each>

请注意使用Attribute Value Templates创建name属性。

答案 1 :(得分:0)

恐怕您不能在单个元素中拥有多个具有相同名称的属性。 也许您应该准备一个用逗号分隔的列表,并将其作为属性的值。