为一个值的出现次数解析单个节点

时间:2012-10-12 23:44:42

标签: xslt

我有一个XML元素,其值类似于以下内容。

<?xml version='1.0' encoding='UTF-8'?>
<Report_Data>
   <Report_Entry>
     <Address>1234 Address Line 1&amp;#xa;Pleasanton, CA 94588&amp;#xa;United States of America</Address>
</Report_Entry>
<Report_Entry>
     <Address>1234 Address Line 1&amp;#xa;5678 Address Line 2&amp;#xa;Pleasanton, CA 94588&amp;#xa;United States of America</Address>
</Report_Entry>
</Report_Data>   

我正在尝试计算以下值的出现次数。

<xsl:variable name="String1" select="'&amp;#xa;'"/>

我希望在输出中提供的是创建一个新变量,第一个记录为2,第二个记录为3。

请注意,我将从For-Each Report_Entry循环运行。

2 个答案:

答案 0 :(得分:1)

您正在寻找的模板是 GetNoOfOccurance

<xsl:template name="GetNoOfOccurance">
    <xsl:param name="String"/>
    <xsl:param name="SubString"/>
    <xsl:param name="Counter" select="0"/>
    <xsl:variable name="sa" select="substring-after($String, $SubString)"/>
    <xsl:choose>
        <xsl:when test="$sa != '' or contains($String, $SubString)">
            <xsl:call-template name="GetNoOfOccurance">
                <xsl:with-param name="String" select="$sa"/>
                <xsl:with-param name="SubString" select="$SubString"/>
                <xsl:with-param name="Counter" select="$Counter + 1"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$Counter"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

以上述方式调用模板: -

<xsl:variable name="searchStr" select="'&amp;#xa;'"/>
<xsl:call-template name="GetNoOfOccurance">
    <xsl:with-param name="String" select="text()"/>
    <xsl:with-param name="SubString" select="$searchStr"/>
</xsl:call-template>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:variable name="searchStr" select="'&amp;#xa;'"/>
        <xsl:for-each select="//Address">
            <xsl:call-template name="GetNoOfOccurance">
                <xsl:with-param name="String" select="text()"/>
                <xsl:with-param name="SubString" select="$searchStr"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="GetNoOfOccurance">
        <xsl:param name="String"/>
        <xsl:param name="SubString"/>
        <xsl:param name="Counter" select="0"/>
        <xsl:variable name="sa" select="substring-after($String, $SubString)"/>
        <xsl:choose>
            <xsl:when test="$sa != '' or contains($String, $SubString)">
                <xsl:call-template name="GetNoOfOccurance">
                    <xsl:with-param name="String" select="$sa"/>
                    <xsl:with-param name="SubString" select="$SubString"/>
                    <xsl:with-param name="Counter" select="$Counter + 1"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$Counter"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

模板 GetNoOfOccurance 取自@Tomalak answer

答案 1 :(得分:1)

你忘了提到XSLT版本。

如果您使用的是XSLT 2.0,最简单的方法是使用tokenize()函数并减去一个,如此...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>

<xsl:variable name="String1" select="'&amp;#xa;'"/>
<xsl:template match="/*">
  <xsl:for-each select="Report_Entry/Address">There are <xsl:value-of select="count(tokenize(concat(' ',.,' '),$String1)) - 1" /> occurrences.
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

...为样本输入提供此输出...

There are 2 occurrences.
There are 3 occurrences.