Использование xsl для разбора вывода xml, использование переменных? - PullRequest
2 голосов
/ 12 апреля 2011

Я пытаюсь проанализировать вывод XML-файла из googletest, чтобы довольно красиво отобразить результаты на html-странице. У меня была справедливая трещина в этом и есть рабочее решение. Осталось сделать только одно. В настоящее время у каждого класса есть заголовок, и каждая функция + тест отображается внизу, я ищу способ извлечь имя функции из атрибута xml, чтобы оно имело свой собственный подзаголовок. Пример ниже


Токовый выход

Имя класса
functionName_testName
functionName_test2Name
function2Name_testName

Желаемый выход

Имя класса
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 в качестве примера, я хотел бы использовать подзаголовок «Initialise» в заголовке процессора пакетов, причем каждый тест описан в подзаголовке

Любой совет о том, как лучше это сделать, был бы очень признателен. Я посмотрел на переменные xsl, но не могу понять, как справиться с невозможностью изменить значение. Также читал немного о шаблонах xsl и рекурсии, но я не уверен, как это будет работать в этой ситуации.

Заранее спасибо

Дуга

1 Ответ

1 голос
/ 12 апреля 2011

Это преобразование создает подзаголовок и имя для каждого тестового случая :

<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>&#xA;</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()

Редактировать : В комментарии ОП уточняется, что он хочет группировать по функциям (устал от плохих вопросов?):

Это преобразование выполняет требуемую группировку:

<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>&#xA;</xsl:text>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

и выдает желаемый результат :

    Subheading: 
        Initialise
  Name:
           IpNotSet

  Name:
           GoodIp

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