在 xslt 处理期间计算 <p> 元素中的特定字母组合

Count specific letter combinations in a <p> element during xslt processing

提问人:ScottD 提问时间:11/3/2023 最后编辑:michael.hor257kScottD 更新时间:11/4/2023 访问量:47

问:

在 xsl 中处理 xhtml 文件时,我需要计算 xhtml 文件中的特定字母组合。

一个例子是单词和&amp;&quot;

计算以下出现的次数<p>

<p>
  enthroned in his gorgeous palace upon the <strike>c</strike>&amp;Capitoline
  <strike>h</strike>&quot;H&quot;ill that a babe slumbering in a manger in the obscure hamlet of Bethlehem a remote province of Asyria
</p>

我希望计数为 1,计数为 2&amp;&quot;

我可以使用 xsl 2.0 或 3.0

斯科特

XML 字符串 XSLT 计数

评论

0赞 michael.hor257k 11/3/2023
我已将您更改为 .&mp;Capitoline&amp;Capitoline

答:

2赞 michael.hor257k 11/3/2023 #1

两者都是字符,而不是文字。您可以使用以下命令计算当前节点中字符的出现次数:&amp;&quot;&amp;

<xsl:value-of select="string-length(replace(., '[^&amp;]', ''))"/>

艺术

<xsl:value-of select="count(string-to-codepoints(.)[.=38])"/>
0赞 Martin Honnen 11/3/2023 #2

在 XPath 4 中,将有一个函数 https://qt4cg.org/specifications/xpath-functions-40/Overview-diff.html#func-characters 因此在已经支持该函数的环境中,您可以执行例如:characters

let $chars := characters(.)
return
  for $char in ('"', '&amp;')
  return 'count(' || $char || '): ' || count($chars[. = $char])

BaseX 小提琴

1赞 Michael Kay 11/3/2023 #3

还有一个简单的 1.0 解决方案:

string-length(.) - string-length(translate(., '&amp;', ''))
0赞 ScottD 11/4/2023 #4

我想出了这个,这个的修改版本。使用 XSLT 计算 XML 中字符串的出现次数它是一个通用的答案,用于计算任何字符串并返回计数。

   <xsl:template match="http:p">
        <xsl:variable name="ltResult" >
            <xsl:call-template name="countWord">
                <xsl:with-param name="pWord" select="'&amp;'"/>
                <xsl:with-param name="pText" select="string-join(text())"/>
                <xsl:with-param name="count" select="0"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="gtResult">
            <xsl:call-template name="countWord">
                <xsl:with-param name="pWord" select="'&quot;'"/>
                <xsl:with-param name="pText" select="string-join(text())"/>
                <xsl:with-param name="count" select="0"/>
            </xsl:call-template>
        </xsl:variable>
                <xsl:message terminate="no">
                    <xsl:value-of
                        select="concat('&amp; : ', $ltResult , ' &quot; : ', $gtResult)"
                    />
                </xsl:message>
                
    </xsl:template>

   <xsl:template name="countWord">
        <xsl:param name="pWord" as="xs:string"/>
        <xsl:param name="pText" as="xs:string"/>
        <xsl:param name="count" as="xs:integer"/>
        <xsl:choose>
            <xsl:when test="contains($pText, $pWord)">
                <xsl:call-template name="countWord">
                    <xsl:with-param name="pWord" select="$pWord"/>
                    <xsl:with-param name="pText" select="concat(' ', substring-after($pText, $pWord))"/>
                    <xsl:with-param name="count" select="$count + 1"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$count"/>
            </xsl:otherwise>
        </xsl:choose>
        
    </xsl:template>

评论

0赞 michael.hor257k 11/4/2023
XSLT 2.0+ 中有更简单的方法,但这不是这个问题的重点。