Как суммировать значения функции xslt, которые она возвращает - PullRequest
0 голосов
/ 29 марта 2020


Привет всем. Моя проблема в том, что я не могу суммировать значения между узлами, которые не равны "пропуску". enter image description here

Мой вывод должен выглядеть примерно так:

6
6

Вот мои html данные

<html xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml">
   <body>
      <h1>example_2</h1>
      <table border="1">
         <tr>
            <td>name_of_file</td>
            <td>global_structure in a code_1</td>
            <td></td>
            <td>global_structure in a code_2</td>
            <td></td>
         </tr>
         <tr>
            <td>name of the file</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>text_var</td>
            <td>text</td>
            <td>funktion</td>
            <td>A1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>;</td>
            <td>;</td>
            <td>funktion</td>
            <td>A2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A2_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A3</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>;</td>
            <td>;</td>
            <td></td>
         </tr>
         <tr>
            <td>name of the file_2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>text_var</td>
            <td>text</td>
            <td>funktion</td>
            <td>A1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>;</td>
            <td>;</td>
            <td>funktion</td>
            <td>A2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A2_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A3</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>;</td>
            <td>;</td>
            <td></td>
         </tr>
         <tr>
            <td>end</td>
            <td></td>
         </tr>
         <tr>
            <td></td>
         </tr>
      </table>
   </body>
   </html>

И мой xslt code:

<?xml version="1.1" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" office:version="1.2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.w3.org/1999/xhtml"
xmlns:mf="http://userfunctions.com/functions"
extension-element-prefixes="mf">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>


  <xsl:template match="/html/body/table/tr">
    <xsl:variable name="number_of_lines_var"  select="mf:number_of_lines()"/>

    <xsl:value-of select="$number_of_lines_var"/>
  </xsl:template>


<xsl:function name="mf:number_of_lines" as="xs:integer">



  <xsl:sequence  

     select="if (./td[1] ='skip')

             then $number_of_lines_var+1

             else $number_of_lines_var"
             />

</xsl:function>

</xsl:stylesheet>

Но единственное, что я получаю, это ошибка:

Переменная number_of_lines_var не была объявлена ​​(или ее объявление не находится в области видимости)

Как можно переопределить переменную внутри области действия функции вне xsl: function ? Существуют ли какие-либо другие решения для вычисления количества узлов с "пропуском" между узлами, которые не равны "пропуску"
Заранее спасибо
PS Тот же код здесь:
https://xsltfiddle.liberty-development.net/bwe3c5/43

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вместо group-starting-with также можно использовать group-adjacent:

  <xsl:function name="mf:skip-sequences" as="xs:integer*">
      <xsl:param name="table" as="element(table)"/>
      <xsl:for-each-group select="$table/tr" group-adjacent="boolean(self::tr[td[1] = 'skip'])">
          <xsl:sequence select="count(current-group())[current-grouping-key()]"/>
      </xsl:for-each-group>
  </xsl:function>

  <xsl:template match="table">
      <xsl:sequence select="mf:skip-sequences(.)"/>
  </xsl:template>
1 голос
/ 30 марта 2020

Ну, сообщение об ошибке означает, что вы не можете объявить переменную в одном шаблоне или функции, а затем получить доступ к ней в другом. В этом отношении XSLT подобен многим другим обычным языкам программирования: переменная имеет область действия c, которая, по сути, представляет собой инструкции, следующие за объявлением переменной, в том же шаблоне или функции.

И решение обычно это означает передачу значения переменной в качестве параметра функции.

Но теперь я действительно запутался в том, что вы пытаетесь достичь, потому что вы инициализируете переменную, вызывая функцию:

<xsl:variable name="number_of_lines_var"  select="mf:number_of_lines()"/>

, а затем в функции, к которой вы пытаетесь получить доступ к значению переменной

<xsl:function name="mf:number_of_lines" as="xs:integer">
  <xsl:sequence  
     select="if (...) then ... else $number_of_lines_var/>
</xsl:function>

, которая кажется полностью круглой.

Попытка выяснить, что вы можете Вы думали, когда писали это, возможно, вы представляли, что вызов функции увеличит значение переменной? Если это так, то, боюсь, вы совершенно не поняли, как работают функциональные языки. Функции не имеют побочных эффектов, а переменные не меняют своего значения.

Я думаю, что решение вашей проблемы совершенно другое и выглядит примерно так:

<xsl:for-each-group select="td" group-starting-with="*[td[1] ne 'skip']">
  <xsl:value-of select="count(current-group())-1"/>
</xsl:for-each-group>

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

...