如何总结 xslt 函数返回的值

How to summarise the values of xslt function which are returned by it


大家好 我的问题是我无法汇总不等于 "skip" 的节点之间的值。

我的输出应该是这样的:

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 代码:

<?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 之外覆盖变量? 是否有任何其他解决方案来计算节点之间 "skip" 不等于 "skip"
的节点数 提前致谢
P.S。同样的代码在这里:
https://xsltfiddle.liberty-development.net/bwe3c5/43

嗯,错误消息意味着您不能在一个模板或函数中声明一个变量,然后在另一个模板或函数中访问它。在这方面,XSLT 与许多其他传统编程语言一样:变量具有静态作用域,本质上是在同一模板或函数中跟随变量声明的指令。

解决方案通常是将变量的值作为参数传递给函数。

但现在我对你想要实现的目标感到非常困惑,因为你通过调用函数来初始化变量:

<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>

这看起来完全是循环的。

试着弄清楚你在写这篇文章时可能在想什么,也许你想象调用函数会增加变量的值?如果是这样,那么恐怕您完全误解了函数式语言的工作原理。函数没有side-effects,变量不改变它们的值。

我认为,您的问题的解决方案完全不同,看起来像这样:

<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>

您需要对其进行一些改进以处理 table 中的 header 和结尾行,但我会把它留给您,因为您对数据的了解比我愿意。

代替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>