XPath获取指定长度的文本

7
我正在尝试创建一个XPath查询,每次获取549个字符的文本。文本应该是关于相关主题的,例如下面的例子中是orangesapplespears。如果页面上不存在包含这些单词的元素,则我希望XPath查询在页面上查找更容易定位/不太具体的文本。

因此,为了澄清,我正在尝试创建一个XPath查询,以查找包含特定类型文本的元素,如果使用以下查询找到549个或更多字符,则完成,如果未找到任何字符或返回的文本少于549个字符,则我希望XPath查询获取页面上任何段落形式的文本(除了按钮、链接、菜单等文本),并返回这个文本的549个字符,如果结果字符串少于549个字符,则我希望将这两个查询用以下内容连接起来:...

   substring(normalize-space(//*[self::p or self::div][contains(text(),'apples') or contains(text(),'oranges') or contains(text(),'pears')]), 0, 549)

我已经尝试解决这个问题很长一段时间了,如果你有任何建议,我将不胜感激!

非常感谢您提前的帮助!

1个回答

11

是的,在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>

您还可以使用 matches() xpath 函数,通过构造一个正则表达式来避免使用太多的 contains() 谓词:

matches( //*[self::p or self::div][matches(text(),'(apples|oranges|bananas)'])

最后,请注意在XPath中使用//*是非常低效的,如果您的文档有一定的体量,您将会看到性能受到影响。我有一个想法告诉我有一种优化方法,但不幸的是我没有时间去研究。


+1,感谢回复!我不知道关于string-length函数。您能否请提供一个基本示例,说明如何使用XPath查询,如果为真,则应用一个完全不同的查询? - AnchovyLegend

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接