如何使用xslt计算输出行数?

如何使用xslt计算输出行数?,xslt,text,line-count,Xslt,Text,Line Count,我正在用XSLT输出文本。我需要计算每个部分的行数并将其写入输出文件。如何做到这一点 我的输出如下: HDR+aaa:bbb' AAA+78901234567890+String1:String2' BBB+123+String' CCC+321:1212' DDD+112211' DDD+121122' XXX+number_of_records+78901234567890' AAA+1234567890+String1:String2' BBB+123+String' CCC+321:12

我正在用XSLT输出文本。我需要计算每个部分的行数并将其写入输出文件。如何做到这一点

我的输出如下:

HDR+aaa:bbb' AAA+78901234567890+String1:String2' BBB+123+String' CCC+321:1212' DDD+112211' DDD+121122' XXX+number_of_records+78901234567890' AAA+1234567890+String1:String2' BBB+123+String' CCC+321:1212' DDD+1212:2121' BBB+123+String' BBB+122+String' CCC+String' XXX+number_of_records+1234567890' HDR+aaa:bbb' AAA+78901234567890+String1:String2' BBB+123+字符串' CCC+321:1212' DDD+112211' DDD+121122' XXX+记录数量+78901234567890' AAA+1234567890+String1:String2' BBB+123+字符串' CCC+321:1212' DDD+1212:2121' BBB+123+字符串' BBB+122+字符串' CCC+字符串' XXX+记录数+1234567890' 记录的数量应包含从AAA到XXX的行数,包括两行。在第一节中,行数应为6,在第二条消息中,行数应为8。每个部分的第一行和最后一行将共享相同的唯一ID号


由于XSLT内部有太多的处理,因此无法从源代码计算行数

只是为了好玩,在您发布输入示例和样式表构建文本输出之前,此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="result" name="result">
        <xsl:param name="pString" select="."/>
        <xsl:variable name="vAfter" select="substring-after($pString, 'AAA+')"/>
        <xsl:choose>
            <xsl:when test="$vAfter!=''">
                <xsl:variable name="vId" 
                        select="substring-before($vAfter, '+')"/>
                <xsl:variable name="vEnd" 
                  select='concat("XXX+number_of_records+",$vId,"&apos;&#xA;")'/>
                <xsl:variable name="vInto" 
                        select="substring-before($vAfter,$vEnd)"/>
                <xsl:value-of 
                        select='concat(substring-before($pString,"AAA+"),
                             "AAA+",
                             $vInto,
                             "XXX+",
                             string-length(translate($vInto,
                                                     translate($vInto,
                                                               "&#xA;",
                                                               ""),
                                                     "")) + 1,
                             "+",$vId,"&apos;&#xA;")'/>
                <xsl:call-template name="result">
                    <xsl:with-param name="pString" 
                        select="substring-after($vAfter,$vEnd)"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pString"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

概念上简单的方法是使用第二阶段流程。获取初始转换的输出(您发布的内容),并通过模板(或类似@Alejandro的样式表)运行它,该模板将其解析为行,并将以
AAA
开头的行分组。。。并以
XXX
结尾。有关如何执行此操作的非常清晰和实用的教程,请参见使用
tokenize()
xsl:analyze string
,以及
xsl:for each group
。然后对每组中的行进行计数,并重新输出每行,将行计数插入XXX记录

但这是低效的,而且有点容易出错,因为您将解析初始输出。为什么要解析样式表内部已有的信息序列化?您可以通过将初始输出更改为XML来避免效率低下,例如

<hdr>
  <section id="78901234567890">
    <!-- It sounds like AAA's ID actually applies to the section? -->
    <AAA String1="..." String2="..."/>
    <BBB .../>
    <!-- no need to include XXX at this stage AFAICT -->
  </section>
  <section id="1234567890">
    ...
  </section>
</hdr>


. (但即使使用单独的样式表处理器,如果可以使用SAX将两个样式表处理器流水线连接在一起,仍然可以避免重新解析中间XML的成本。)在XSLT 2.0中,可以使用另一个模板处理一个模板的XML输出,没有限制。

我的解决方案:我创建了一个扩展函数,每次调用它时,它会将记录的数量增加一个。我使用xsl:comment来抑制输出,直到我真的需要输出数字。我在每个XXX+行之后重置\u记录的数量


分两步操作会带来太多麻烦。

如果没有输入或示例,没有人能在这里为您提供太多帮助。您使用的是XSLT1还是XSLT2;您使用的是什么处理器?同时发布您的XSLT,因为这是识别所需内容所必需的
HDR+aaa:bbb'
AAA+78901234567890+String1:String2'
BBB+123+String'
CCC+321:1212'
DDD+112211'
DDD+121122'
XXX+6+78901234567890'
AAA+1234567890+String1:String2'
BBB+123+String'
CCC+321:1212'
DDD+1212:2121'
BBB+123+String'
BBB+122+String'
CCC+String'
XXX+8+1234567890'
<hdr>
  <section id="78901234567890">
    <!-- It sounds like AAA's ID actually applies to the section? -->
    <AAA String1="..." String2="..."/>
    <BBB .../>
    <!-- no need to include XXX at this stage AFAICT -->
  </section>
  <section id="1234567890">
    ...
  </section>
</hdr>