是的。xpath 中有一个string-length()
函数可以在谓词中使用:
substring(normalize-space(//*[string-length( text()) > 549 and (... other conditions ...)]),0,549)
请参阅“ XPath 中是否有“if -then - else”语句? ”了解如何执行条件语句来确定是否需要添加省略号。
从上面的 SO 问题中改编一个例子:
if (fn:string-length(normalize-space(//*[self::p or self::div][contains(text(),'apples']) > 549)
then (concat( fn:substring(normalize-space(//*[self::p or self::div][contains(text(),'apples']), 0, 5490), "...") )
else (normalize-space(//*[self::p or self::div][contains(text(),'apples']))
在我看来,这在 XPath 中确实很复杂。如果您可以使用 XQuery,那么您将获得一个更具可读性的转换:
for $text in normalize-space(//*[self::p or self::div])
where $text[contains(text(),'apples' or ...]
return
if (string-length( $text) > 549) then
concat( substring( $text, 0, 549), "...")
else
$text
我怀疑这实际上可以通过多个嵌套的 for 语句进一步优化(以提高可读性、维护性),以处理您需要的各种结果。
如果使用 XSL:
<xsl:template match="//*[self::p or self::div][contains(text(),'apples' or ...]">
<xsl:variable name="text" select="normalize-space( . )" />
<xsl:choose>
<xsl:when test="string-length( $text)">
<xsl:value-of select="substring( $text, 0, 549)"/>...
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
您还可以使用xpath 函数,通过构造正则表达式matches()
来避免有这么多谓词:contains()
matches( //*[self::p or self::div][matches(text(),'(apples|oranges|bananas)'])
最后,请注意在 XPath 中使用//
and*
效率非常低,如果您的文档对它有任何影响,您将看到性能影响。我有一种痒,告诉我有办法优化它,但不幸的是我没有时间研究。