Уменьшить повторение выражения в XSLT 1.0 - PullRequest
3 голосов
/ 22 июня 2010

У меня есть следующий XML (упрощение):

<?xml version="1.0" encoding="utf-8"?>
<TestCases>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type2</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Passed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
</TestCases>

Мне интересно создать таблицу, которая подсчитывает количество пройденных / не пройденных тестовых случаев в соответствии с их типом, например так:

пройдено (Type1): 1 Ошибка (Тип 1): 1 Прошло (Другие типы): 0 Не удалось (Другие типы): 1

Для этого я пишу следующий запрос:

<xsl:value-of select="count(//TestCase[Result = 'Passed' and count(Properties/TestType='Type1')>0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Failed' and count(Properties/TestType='Type1')>0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Passed' and count(Properties/TestType='Type1')=0])"/>
<xsl:value-of select="count(//TestCase[Result = 'Failed' and count(Properties/TestType='Type1')=0])"/>

Как видите, много повторений кода, и было бы здорово, если бы я мог сохранить некоторые из них. Я понимаю, что в XSL 2.0 я мог бы использовать для этого пользовательские функции, но что мне делать в XSL 1.0? Видите ли вы какие-либо варианты оптимизации повторяющихся выражений?

P.S. Обратите внимание, что это упрощение реального, и хотя выражение здесь не кажется длинным, в реальном коде оно намного длиннее, поэтому необходимость вполне реальна.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 22 июня 2010

Попробуйте:

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

    <xsl:key name="byType" match="Properties/Type" use="."/> 

    <xsl:template match="text()" /> 

    <xsl:template match="Type[count(.|key('byType',.)[1])=1]"> 
        <xsl:value-of select="concat(' Passed (',.,'): ',
                                      count(key('byType',.)[../../Result='Passed']),
                                      ' Failed (',.,'): ',
                                      count(key('byType',.)[../../Result='Failed']))" /> 
    </xsl:template>  

</xsl:stylesheet> 

И вы получите:

 Passed (Type1): 1 Failed (Type1): 1 Passed (Type2): 0 Failed (Type2): 1

Редактировать : менее многословно.

1 голос
/ 22 июня 2010

В дополнение к отличному решению bu @Alejandro, использующему метод группировки Мюнхена для группирования, здесь показано, что иллюстрирует использование переменных :

Это преобразование:

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

 <xsl:variable name="vPassed"
      select="/*/*[Result = 'Passed']"/>

 <xsl:variable name="vFailed"
      select="/*/*[Result = 'Failed']"/>

 <xsl:template match="/">
  <xsl:value-of select=
   "concat('Passed (Type1): ',
           count($vPassed[Properties/Type='Type1']),
           ' Failed (Type1): ',
           count($vFailed[Properties/Type='Type1']),
           ' Passed (Other types): ',
           count($vPassed[not(Properties/Type='Type1')]),
           ' Failed (Other types): ',
           count($vFailed[not(Properties/Type='Type1')])
          )
   "/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<TestCases>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Failed</Result>
    <Properties>
      <Type>Type2</Type>
    </Properties>
  </TestCase>
  <TestCase>
    <Name>Test1</Name>
    <Result>Passed</Result>
    <Properties>
      <Type>Type1</Type>
    </Properties>
  </TestCase>
</TestCases>

дает требуемый, правильный результат :

Passed (Type1): 1 Failed (Type1): 1 Passed (Other types): 0 Failed (Other types): 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...