如何在XSLT v1.0中使用通配符或字符串模式匹配?
在XSLT 1.0里实现字符串模式匹配其实有几种实用的方案,刚好你的场景是要匹配以PD_STATEFUL_开头的Cookie节点,我给你详细拆解下:
1. 用XSLT 1.0原生字符串函数(最稳妥,无需扩展)
这是最常用的方式,不需要依赖任何扩展,兼容性拉满。针对你的场景,starts-with()函数完全适用:
匹配前缀(比如PD_STATEFUL_开头的Cookie)
直接用starts-with(@name, 'PD_STATEFUL_')来筛选节点,示例代码如下:
<!-- 匹配所有name属性以PD_STATEFUL_开头的Cookie节点 --> <xsl:template match="Cookie[starts-with(@name, 'PD_STATEFUL_')]"> <!-- 这里写你的处理逻辑,比如输出Value值 --> <xsl:value-of select="Value"/> <xsl:text> </xsl:text> <!-- 换行 --> </xsl:template>
如果需要匹配包含某个子串的节点,用contains()函数就行,比如找name里带STATEFUL的Cookie:
Cookie[contains(@name, 'STATEFUL')]
如果需要匹配后缀,XSLT 1.0没有原生的ends-with(),可以自己用substring+string-length实现:
<!-- 匹配name以`_888d`结尾的Cookie --> Cookie[substring(@name, string-length(@name) - 4 + 1) = '_888d']
2. 用正则表达式(需要处理器支持EXSLT扩展)
XSLT 1.0本身没有原生正则支持,但很多主流处理器(比如libxslt、Apache Xalan)支持EXSLT的正则扩展。如果需要更复杂的模式匹配,可以试试这个:
首先要在样式表里引入EXSLT的命名空间:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="regexp">
然后用regexp:test()函数来匹配,比如匹配PD_STATEFUL_开头的任意字符串:
<xsl:template match="Cookie[regexp:test(@name, '^PD_STATEFUL_.*$')]"> <!-- 处理逻辑 --> </xsl:template>
注意:如果你的XSLT处理器不支持EXSLT,这个方法就用不了,所以优先推荐原生函数。
3. 完整示例(针对你的XML)
先修正下你XML里的标签错误(应该用<Cookies>包裹所有<Cookie>节点),假设你的XML结构是:
<Cookies> <Cookie name="PD_STATEFUL_2707f5b6-48e3-11e8-bb87-000c2953888d"> <Value>%2Fportal</Value> <Path>/</Path> <Domain></Domain> <Expires></Expires> <Secure>0</Secure> <HTTPOnly>0</HTTPOnly> </Cookie> <Cookie name="PD_STATEFUL_2808f5b6-48e3-11e8-bb87-000c2953180d"> <Value>%2Fwasapp</Value> <Path>/</Path> <Domain></Domain> <Expires></Expires> <Secure>0</Secure> <HTTPOnly>0</HTTPOnly> </Cookie> <Cookie name="Normal_Cookie"> <Value>test</Value> </Cookie> </Cookies>
对应的XSLT样式表,提取所有目标Cookie的Value:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="yes"/> <xsl:template match="/"> <xsl:text>匹配到的Cookie值: </xsl:text> <xsl:for-each select="Cookies/Cookie[starts-with(@name, 'PD_STATEFUL_')]"> <xsl:text>- </xsl:text> <xsl:value-of select="Value"/> <xsl:text> </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
运行后会输出:
匹配到的Cookie值: - %2Fportal - %2Fwasapp
额外技巧:忽略大小写匹配
如果需要忽略大小写(比如匹配pd_stateful_或者PD_Stateful_),可以用translate()把字符串转成统一大小写再比较:
Cookie[starts-with(translate(@name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'pd_stateful_')]
内容的提问来源于stack exchange,提问作者user9727543

