XSLT 2.0字符串数组处理:判断前缀一致性并返回对应结果
解决XML中
<a>元素的一致性判断问题 需求回顾
给定XML中的<a>元素,需判断所有元素去掉最后一个字符后的内容是否完全一致:
- 一致:返回第一个
<a>元素的值 - 不一致:抛出异常或返回硬编码值
示例1(合法,返回1232)
<test> <a>1232</a> <a>1236</a> <a>1239</a> </test>
示例2(非法,需报错)
<test> <a>1232</a> <a>1136</a> <a>1239</a> </test>
问题解答
1. 如何将转换后的结果存入变量$all_transformed_As
根据你使用的XSLT版本,实现方式不同:
XSLT 1.0(无原生序列支持)
XSLT 1.0无法直接存储字符串序列,需要通过生成临时节点集来实现:
<xsl:variable name="all_As" select="/test/a"/> <xsl:variable name="all_transformed_As"> <xsl:for-each select="$all_As"> <!-- 生成临时节点存储转换后的值 --> <val><xsl:value-of select="substring(., 1, string-length(.) - 1)"/></val> </xsl:for-each> </xsl:variable> <!-- 使用扩展函数将临时树转为节点集(需处理器支持,如libxslt、Xalan) --> <xsl:variable name="transformed_nodes" select="exsl:node-set($all_transformed_As)/val"/>
之后可通过$transformed_nodes访问所有转换后的值。
XSLT 2.0+(支持序列)
直接通过序列表达式生成,写法更简洁:
<xsl:variable name="all_As" select="/test/a"/> <xsl:variable name="all_transformed_As" select="$all_As/substring(., 1, string-length(.) - 1)"/>
$all_transformed_As会直接存储所有转换后的字符串序列。
2. 更简便的实现方式(无需存储所有转换值)
其实不需要先存储所有转换后的值,直接通过对比所有元素与第一个元素的转换结果即可完成判断,更高效:
XSLT 1.0实现
<xsl:template match="/"> <xsl:variable name="first_a" select="/test/a[1]"/> <xsl:variable name="first_transformed" select="substring($first_a, 1, string-length($first_a) - 1)"/> <!-- 检查是否存在不符合的<a>元素 --> <xsl:if test="/test/a[substring(., 1, string-length(.) - 1) != $first_transformed]"> <!-- 抛出终止异常 --> <xsl:message terminate="yes">错误:所有<a>元素去掉最后一位后内容不一致</xsl:message> <!-- 若不需要终止,可替换为返回硬编码值:<xsl:value-of select="'INVALID'"/> --> </xsl:if> <!-- 所有元素符合条件,返回第一个<a>的值 --> <xsl:value-of select="$first_a"/> </xsl:template>
XSLT 2.0+实现(更简洁)
利用distinct-values函数直接判断唯一性:
<xsl:template match="/"> <xsl:variable name="transformed_values" select="/test/a/substring(., 1, string-length(.) - 1)"/> <xsl:if test="count(distinct-values($transformed_values)) != 1"> <xsl:message terminate="yes">错误:所有<a>元素去掉最后一位后内容不一致</xsl:message> <!-- 或返回硬编码值:<xsl:value-of select="'INVALID'"/> --> </xsl:if> <xsl:value-of select="/test/a[1]"/> </xsl:template>
内容的提问来源于stack exchange,提问作者erkesh
相关产品推荐
相关产品推荐

