XSLT 2.0:仅匹配子元素值符合正则表达式的模板问题
XSL筛选匹配正则的card元素问题
原始XML数据
<root> <card> <k>заада</k> <blockquote>заада I</blockquote> <blockquote>ир.</blockquote> <blockquote>(или жүрөк заада)</blockquote> </card> ... </root>
需求
筛选出所有包含子元素blockquote且其文本匹配正则表达式^\w+-? I:?$的card元素。
有问题的XSL代码
<xsl:template match="/"> <xsl:apply-templates select="//card[matches(blockquote, '^\w+-? I:?$')]"/> </xsl:template> <xsl:template match="card"> <xsl:copy-of select="." /> </xsl:template>
问题分析与修正
问题点
matches函数仅接受单个字符串作为输入参数,当card下存在多个blockquote时,直接传入节点集会导致函数调用错误。- 正则中的
\w仅匹配ASCII字母数字,无法匹配XML中的西里尔字母(如заада),导致匹配逻辑失效。
修正后的XSL代码
<xsl:template match="/"> <!-- 检查card下是否存在至少一个blockquote匹配正则 --> <xsl:apply-templates select="//card[exists(blockquote[matches(., '^[\p{L}]+-? I:?$', 'u')])]"/> </xsl:template> <xsl:template match="card"> <xsl:copy-of select="." /> </xsl:template>
修正说明
- 使用
blockquote[matches(., ...)]遍历每个blockquote元素,对单个元素的文本调用matches函数,再通过exists()判断是否存在匹配项。 - 将
\w替换为Unicode字母类[\p{L}],并添加'u'标志启用Unicode匹配模式,确保能正确匹配西里尔字母。 - 注意:
matches函数是XSLT 2.0及以上版本的特性,需使用支持该版本的处理器(如Saxon)。
内容的提问来源于stack exchange,提问作者xinatanil
相关产品推荐
相关产品推荐

