Шаблон XSL-преобразования возвращает только последнее значение атрибута - PullRequest
0 голосов
/ 10 января 2019

Привет и с новым годом сообщество переполнения стека! Я впервые работаю с 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 и перечислить атрибуты «name», которые я думал. Но результат таков:

    <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 голосов
/ 10 января 2019

Боюсь, вы не можете иметь несколько атрибутов с одинаковыми именами в одном элементе. Возможно, вам следует подготовить список через запятую и указать его в качестве значения атрибута.

0 голосов
/ 10 января 2019

Вам нужно переместить создание <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>

Обратите внимание на использование шаблонов значений атрибутов для создания атрибута name.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...