2014-02-19 5 views
0

Мне нужна помощь по XSLT, пожалуйста.Подсчитайте количество строк в XSLT1.0

У меня есть XML-файл, и мне нужно сообщить некоторые данные дважды в файл, и данные, необходимые для фильтрации, должны быть отфильтрованы.

, а на нижнем колонтитуле мне нужно сообщить, сколько строк в файле.

Может кто-то пожалуйста, помогите мне здесь спасибо

Вот мой XML:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
<ns0:File xmlns:ns0="file"> 

    <ns0:Records> 
    <ns0:Main> 
     <ns0:Info> 
     <ns0:InternalCode>1</ns0:InternalCode> 
     <ns0:Name>test1</ns0:Name> 
     <ns0:Factor>2.000000000000</ns0:Factor> 
     <ns0:Type>a</ns0:Type> 
     </ns0:Info> 
    </ns0:Main> 
<ns0:Main> 
     <ns0:Info> 
     <ns0:InternalCode>2</ns0:InternalCode> 
     <ns0:Name>test2</ns0:Name> 
     <ns0:Factor>10.000000000000</ns0:Factor> 
     <ns0:Type>c</ns0:Type> 
     </ns0:Info> 
    </ns0:Main> 
<ns0:Main> 
     <ns0:Info> 
     <ns0:InternalCode>3</ns0:InternalCode> 
     <ns0:Name>test3</ns0:Name> 
     <ns0:Factor>13.000000000000</ns0:Factor> 
     <ns0:Type>b</ns0:Type> 
     </ns0:Info> 
    </ns0:Main> 
<ns0:Main> 
     <ns0:Info> 
     <ns0:InternalCode>4</ns0:InternalCode> 
     <ns0:Name>test4</ns0:Name> 
     <ns0:Factor>1.000000000000</ns0:Factor> 
     <ns0:Type>a</ns0:Type> 
     </ns0:Info> 
    </ns0:Main> 
<ns0:Main> 
     <ns0:Info> 
     <ns0:InternalCode>5</ns0:InternalCode> 
     <ns0:Name>test5</ns0:Name> 
     <ns0:Factor>1.000000000000</ns0:Factor> 
     <ns0:Type>f</ns0:Type> 
     </ns0:Info> 
    </ns0:Main> 
    </ns0:Records> 

    <ns0:Footer> 
    <ns0:Time>10:54:40</ns0:Time> 
    <ns0:NumberOfRecords>5</ns0:NumberOfRecords> 
    </ns0:Footer> 

</ns0:File> 

А вот мой XSLT:

<?xml version="1.0" encoding="iso-8859-1"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="file"> 

     <xsl:output method="text" 
     encoding="ASCII"/> 

     <xsl:template match="ns0:Main"> 

<xsl:variable name="substractone"> 
     <xsl:value-of select="ns0:Info/ns0:Factor-1"/> 
    </xsl:variable> 

     <xsl:if test=" ns0:Factor !=0 and ns0:Type !='c' and $substractone !=0 "> 


      <xsl:choose> 
      <xsl:when test="ns0:Type = 'a'"> 

       <xsl:value-of select="ns0:InternalCode"/> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Name"/> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Factor"/> 
         <xsl:text> 
    </xsl:text> 
    <!-- repeat in a new line --> 
       <xsl:value-of select="ns0:InternalCode"/> 

       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Name"/> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Factor"/> 
         <xsl:text> 
    </xsl:text> 

      </xsl:when> 

      <xsl:otherwise> 


       <xsl:value-of select="ns0:InternalCode"/> 

       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Name"/> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="ns0:Factor"/> 
         <xsl:text> 
    </xsl:text> 
      </xsl:otherwise> 
      </xsl:choose> 


     </xsl:if> 

     </xsl:template> 

     <xsl:template match="ns0:Footer"> 
     <!--Footer row--> 
     <xsl:text> 
    </xsl:text> 

     <xsl:text>*</xsl:text> 
     <xsl:value-of select="ns0:NumberOfRecords"/> 



     <!--record total--> 


     <xsl:apply-templates/> 

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

    </xsl:stylesheet> 

Как вы можете видеть ns0: NumberOfRecords бы вернули 5 здесь, но на самом деле этот файл получил 4 строки (фильтрация типа = c и 2 строки для каждого типа = a)

Может кто-нибудь, пожалуйста, скажите, как я могу правильно получить количество строк в файле?

+0

Вы, очевидно, смотрели на мой ответ (так как вы исправлены ошибки в коде, который я указываю). Не могли бы вы сказать мне, решила ли ваша проблема? Кстати, пожалуйста, примите один из ответов здесь: http://stackoverflow.com/questions/12743828/how-to-do-square-root-in-xslt-1-0 –

ответ

0

Как вы можете видеть ns0: NumberOfRecords вернулся бы 5 здесь, но на самом деле этот файл получил 6 строк (фильтрации типа = с и 2 строки для каждого типа = а)

Вместо

<xsl:value-of select="ns0:NumberOfRecords"/> 

написать

<xsl:value-of select="count(//ns0:Type[. != 'c']) + count(//ns0:Type[. = 'a'])"/> 

Тогда вы получите следующий результат:

*6 

Другие проблемы, связанные с вашим XML и код:

  • ни один из вашего xsl:if и xsl:choose принимает значение "истина". Таким образом, единственное, что выводится, это общее количество записей. Это связано с контекстом .

В контексте я имею в виду следующее. Ваш шаблон соответствует ns0:Main элементам, и поэтому это «ваша» позиция в дереве. Теперь линия, как это:

<xsl:if test=" ns0:Factor !=0 and ns0:Type !='c' "> 

на самом деле ищет ns0:Factor и ns0:Type элементов, которые являются непосредственными дети ns0:Main элемента. Но, как вы знаете, таких элементов нет. Вместо этого ns0:Factor и ns0:Type являются детьми ns0:Info.Вы должны учитывать этот факт:

<xsl:if test=" ns0:Info/ns0:Factor !=0 and ns0:Info/ns0:Type !='c' "> 

Или, возможно, было бы легче изменить матч шаблона:

<xsl:template match="ns0:Main/ns0:Info"> 

Если вы делаете одно из этих изменений, выход:

1,test1,1.000000000000 
1,test1,1.000000000000 
3,test3,13.000000000000 
4,test4,1.000000000000 
4,test4,1.000000000000 
5,test5,1.000000000000 

*6 
  • вы не объявить пространство имен XSLT (xmlns:xsl="http://www.w3.org/1999/XSL/Transform") в таблице стилей
  • во входной XML, есть излишек </ns0:Records> элемент, который закрывает преждевременно и предотвращает файл от хорошо сформированных
+0

спасибо большое. однако это просто упрощенные примеры. У меня есть некоторые дополнительные фильтры, основанные на переменной, объявленной в разделе ns0: Main. Мне нужно было бы снова объявить их под ns0: Footer снова? но я не думаю, что re-delacre они будут работать на нижнем колонтитуле, так как каждой переменной понадобятся данные в ns0: Main для каждой записи – ken

+0

Для ваших будущих вопросов, упрощая данные XML, убедитесь, что вы только устраняете материю, которая делает не способствуют вашей проблеме. В XSLT нет такого понятия, как «фильтр». Что ты имеешь в виду? Невозможно сказать, является ли ваш подход «правильным», не видя фактическую таблицу стилей. –

+0

или, может быть, я могу объявить footerwithin Main, но как cna я просто заставляю его появляться однажды? – ken

Смежные вопросы