如何在XSLT中提取字符串内不区分大小写的SR#后的数字并解决报错
解决XSLT提取邮件主题中SR编号的问题
看起来你遇到的问题主要来自两个方面:XSLT版本兼容性和输出结构不符合预期,咱们一步步来解决:
问题分析
- XSLT版本限制:
<xsl:analyze-string>是XSLT 2.0及以上才支持的函数,如果你的运行环境是XSLT 1.0,直接使用这个语法会导致加载XSLT文件失败,也就是你看到的Error in loading Hierarchical Object XSLT file(s)错误。 - 输出结构错误:即使在XSLT 2.0环境下,你当前的代码在
Field元素内部生成了<SR>子元素,但Field应该直接包含编号文本,这种嵌套结构不符合目标XML的要求,所以不会正确显示编号。
解决方案
方案1:XSLT 2.0及以上环境(推荐)
修正代码结构,去掉不必要的<SR>元素,直接将正则匹配到的编号作为Field的文本内容,同时确保正则不区分大小写:
<xsl:when test="matches($subject, '\s*[Ss][Rr]#\d+\s*')"> <!-- 输出父对象类型 --> <xsl:element name="Field"> <xsl:attribute name="Name">a_eco_parentObjectType</xsl:attribute> <xsl:text>ServiceReq</xsl:text> </xsl:element> <!-- 输出父对象ID --> <xsl:element name="Field"> <xsl:attribute name="Name">a_eco_parentObjectID</xsl:attribute> <xsl:value-of select="replace($subject, '.*\s*[Ss][Rr]#(\d+)\s*.*', '$1')"/> </xsl:element> </xsl:when>
关键点:
- 用
matches()替代contains(),更精准判断是否包含不区分大小写的SR# - 用
replace()函数直接提取编号:通过正则捕获组$1获取SR#后的数字,替换整个主题为捕获到的编号,避免使用<xsl:analyze-string>带来的结构问题 - 正则
.*\s*[Ss][Rr]#(\d+)\s*.*确保匹配任意位置的SR#(大小写混合),并捕获后面的连续数字
方案2:XSLT 1.0环境(兼容旧系统)
如果你的环境只支持XSLT 1.0,需要用字符串处理函数来模拟正则提取,因为1.0没有原生正则支持:
<xsl:when test="contains(translate($subject, 'sr', 'SR'), 'SR#')"> <!-- 输出父对象类型 --> <xsl:element name="Field"> <xsl:attribute name="Name">a_eco_parentObjectType</xsl:attribute> <xsl:text>ServiceReq</xsl:text> </xsl:element> <!-- 输出父对象ID --> <xsl:element name="Field"> <xsl:attribute name="Name">a_eco_parentObjectID</xsl:attribute> <xsl:variable name="srStart" select="string-length(substring-before(translate($subject, 'sr', 'SR'), 'SR#')) + 4"/> <xsl:variable name="srNumber" select="substring($subject, $srStart)"/> <xsl:variable name="cleanNumber" select="substring-before(concat($srNumber, ' '), ' ')"/> <xsl:value-of select="$cleanNumber"/> </xsl:element> </xsl:when>
关键点:
- 用
translate($subject, 'sr', 'SR')把主题里的小写s/r转成大写,实现不区分大小写的SR#判断 - 通过
substring-before找到SR#的位置,计算出编号的起始索引 - 用
substring-before(concat($srNumber, ' '), ' ')提取第一个空格前的内容,确保只获取连续数字编号
验证测试
用你的测试主题RE: SR#51417: D_SATTER-NOV60LKA-I_G-A0201244测试,两种方案都会输出:
<Field Name="a_eco_parentObjectType">ServiceReq</Field> <Field Name="a_eco_parentObjectID">51417</Field>
这样应该就能解决你遇到的加载错误和编号不显示的问题了。
内容的提问来源于stack exchange,提问作者LondonKiwi
相关产品推荐
相关产品推荐

