如何获取含文本的<p>标签子串,过滤无文本/仅含图片的段落?
解决XSLT筛选首个含文本的
<p>标签问题 嘿,这个问题我之前也碰到过——用字符串截取HTML确实容易踩坑,尤其是要过滤空段落或者只有图片的段落的时候。咱们换个思路,别纠结字符串截取,直接用XSLT的节点选择能力来处理,会靠谱得多!
核心思路
你的核心需求是找到第一个包含非空白文本的<p>标签,而不是单纯截取第一个<p>。要实现这个,得先把存储的HTML字符串转换成可操作的节点集,再用XPath筛选符合条件的节点,而不是靠字符串截取。
具体实现方案
如果你用的是XSLT 3.0
XSLT 3.0内置了xsl:parse可以直接解析HTML字符串为节点集,代码可以这么写:
<!-- 第一步:把HTML字符串解析成节点集 --> <xsl:variable name="parsed-html"> <xsl:parse select="$copy" /> </xsl:variable> <!-- 第二步:筛选第一个包含有效文本的<p>标签 --> <xsl:variable name="first-valid-paragraph" select="$parsed-html//p[normalize-space() != ''][1]" /> <!-- 第三步:输出内容和链接 --> <xsl:if test="$first-valid-paragraph"> <xsl:copy-of select="$first-valid-paragraph/node()" disable-output-escaping="yes" /> <a href="{$currentPage/url}" title="{$currentPage/title}: {@nodeName}"> Continue reading... </a> </xsl:if>
如果你用的是XSLT 1.0
XSLT 1.0没有内置的HTML解析,需要借助EXSLT的node-set()函数来把字符串转成节点集:
<!-- 第一步:把转义的HTML字符串还原并转为节点集 --> <xsl:variable name="html-content"> <xsl:value-of select="$copy" disable-output-escaping="yes" /> </xsl:variable> <xsl:variable name="html-node-set" select="exslt:node-set($html-content)" /> <!-- 第二步:筛选第一个包含有效文本的<p>标签 --> <xsl:variable name="first-valid-paragraph" select="$html-node-set//p[normalize-space() != ''][1]" /> <!-- 第三步:输出内容和链接 --> <xsl:if test="$first-valid-paragraph"> <xsl:copy-of select="$first-valid-paragraph/node()" disable-output-escaping="yes" /> <a href="{$currentPage/url}" title="{$currentPage/title}: {@nodeName}"> Continue reading... </a> </xsl:if>
关键解释
normalize-space() != '':这个XPath条件会检查<p>标签的所有后代文本内容,去掉首尾空白后是否为空。如果<p>里只有<img />,它的字符串值是空的,就会被过滤掉;如果包含文本(哪怕同时有其他元素),就会被选中。- 为什么不用字符串截取?因为HTML结构可能有变化(比如
<p>带属性、嵌套其他元素),字符串截取很容易出错,而节点选择是基于DOM结构的,更稳定可靠。
内容的提问来源于stack exchange,提问作者nickornotto
相关产品推荐
相关产品推荐

