XSL как посчитать количество узлов в зависимости от значения без использования атрибутов и без учета регистра - PullRequest
1 голос
/ 18 мая 2011

Я недавно начал изучать XSL.Я хотел бы использовать его для преобразования моего файла XML в HTML.Данные, которые я хочу извлечь, должны представить, сколько узлов имеют определенное значение.

XML имеет следующую структуру:

<Tests> 
   <Test> 
        <TestName> a </TestName>  
        <Date> 12.11.10 </Date>       
        <Result> Pass</Result> 
   </Test>   
   <Test> 
       <TestName> b </TestName>      
       <Date> 13.11.10 </Date> 
       <Result> Fail </Result> 
   </Test>
    <Test>
        <TestName> c </TestName>         
        <Date> 14.11.10 </Date>     
        <Result> Pass </Result>   
    </Test>
</Tests> 

Для этого xml я получил вывод как -> 2 (числоПроходит) 1 (количество неудач)

xsl для указанного выше xml ::

<xsl:key name="kTestByResult" match="Test" use="normalize-space(Result)"/> 
<xsl:template match="/">         
 <xsl:value-of select="concat(count(key              
 ('kTestByResult','Fail')),' (number of Fails) ',
  count(key'kTestByResult','Pass')),'(number of Passes)')"/>     
 </xsl:template> 

Здесь может быть проход (PASS / pass / Pass).В любой ситуации я хочу получить результат в 2 прохода.

любой дает некоторое представление об этом ???

Ответы [ 3 ]

1 голос
/ 18 мая 2011

Попробуйте это:

<xsl:key name="kTestByResult" match="Test" use="normalize-space(
  translate(Result,
  'qwertyuiopasdfghjklzxcvbnm',
  'QWERTYUIOPASDFGHJKLZXCVBNM'))"/> 

<xsl:template match="/">         
 <xsl:value-of select="concat(
   count(key('kTestByResult','FAIL')),
   ' (number of Fails) ',
   count(key('kTestByResult','PASS')),
   '(number of Passes)')"/>     
 </xsl:template> 

Это преобразует все значения в верхний регистр, а затем просто передает верхний регистр 'PASS' или 'FAIL' в функцию ключа.

1 голос
/ 18 мая 2011

Это более общее решение, которое перечисляет количество всех различных значений Result без их жесткого кодирования - например, если документ XML изменяется так, что появляются результаты SKIP или INDECISIVE,эти новые значения также будут перечислены и подсчитаны:

<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:variable name="vLower" select=
 "'abcdefghijklmnopqrstuvwxyz'"/>

 <xsl:variable name="vUpper" select=
 "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

 <xsl:key name="kResultByVal" match="Result"
  use="translate(normalize-space(),
                 'abcdefghijklmnopqrstuvwxyz',
                 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>

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

 <xsl:template match=
  "Result
   [generate-id()
   =
    generate-id(key('kResultByVal',
                     translate(normalize-space(),
                               'abcdefghijklmnopqrstuvwxyz',
                               'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                               )
                    )[1])
   ]
   ">
   <xsl:text>&#xA;</xsl:text>
  <xsl:value-of select="translate(normalize-space(),$vLower,$vUpper)"/>
  <xsl:text>: </xsl:text>
  <xsl:value-of select=
   "count(key('kResultByVal',
              translate(normalize-space(),
                        $vLower,
                        $vUpper
                        )
              )
          )
   "/>
 </xsl:template>
</xsl:stylesheet>

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

<Tests>
    <Test>
        <TestName> a </TestName>
        <Date> 12.11.10 </Date>
        <Result> Pass</Result>
    </Test>
    <Test>
        <TestName> b </TestName>
        <Date> 13.11.10 </Date>
        <Result> Fail </Result>
    </Test>
    <Test>
        <TestName> c </TestName>
        <Date> 14.11.10 </Date>
        <Result> Pass </Result>
    </Test>
</Tests>

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

PASS: 2
FAIL: 1

II.Решение XSLT 2.0, которое дает тот же результат :

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:for-each-group select="//Result"
                         group-by="normalize-space(upper-case(.))">
      <xsl:sequence select=
      "normalize-space(upper-case(.)),
       count(current-group()),
       '&#xA;'
      "/>
     </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>
1 голос
/ 18 мая 2011

Перевод символов верхнего регистра в нижний регистр:

<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower-case" select="'abcdefghijklmnopqrstuvwxyz'"/>

<xsl:key name="kTestByResult" match="Test" use="translate( normalize-space(Result), $upper-case, $lower-case )"/> 

<xsl:template match="/">         
    <xsl:value-of select="concat( 
        count( key('kTestByResult', 'fail') ), ' (number of Fails) ',
        count( key('kTestByResult', 'pass') ), '(number of Passes)'
    )"/>     
</xsl:template> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...