You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT中使用XPath解析并比较两个QName?

如何在XSLT中使用XPath解析并比较两个QName?

嘿,我完全懂你的需求——你想把输入XML里属性的QName值,和XSLT里定义的QName,各自按照它们所在文档的命名空间声明解析后再做相等性比较对吧?你的示例里现在没法得到预期的"Success",核心问题是直接拿字符串比QName根本不靠谱,前缀只是个命名空间的别名,不同前缀可能指向同一个命名空间,必须拆成命名空间URI和本地名两部分来对比才准确。

针对你用的XSLT 1.0,我们可以手动拆分QName的前缀和本地名,再分别验证对应的命名空间URI和本地名是否匹配,修改后的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
xmlns:aTest="http://tempuri.org/Test"
>
<xsl:output method="xml" indent="yes"/>

<!-- 存储我们要匹配的目标命名空间URI -->
<xsl:variable name="target-namespace" select="namespace-uri('aTest')"/>
<!-- 存储要匹配的目标本地名 -->
<xsl:variable name="target-local-name" select="'a'"/>

<xsl:template match="@* | node()">
  <xsl:variable name="input-qname" select="/root/@name"/>
  <!-- 提取输入QName的前缀(冒号之前的部分) -->
  <xsl:variable name="input-prefix" select="substring-before($input-qname, ':')"/>
  <!-- 提取输入QName的本地名:有冒号就取后面的,没有就全取 -->
  <xsl:variable name="input-local-name" select="if (contains($input-qname, ':')) then substring-after($input-qname, ':') else $input-qname"/>
  
  <!-- 根据输入文档的命名空间上下文,获取前缀对应的URI -->
  <xsl:variable name="input-namespace" select="namespace-uri-for-prefix($input-prefix, /root)"/>
  
  <!-- 同时匹配命名空间URI和本地名才判定相等 -->
  <xsl:if test="$input-namespace = $target-namespace and $input-local-name = $target-local-name">
    Success
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

为什么这样就能生效呢?我给你拆解下:

  • namespace-uri('aTest')会直接获取XSLT文档里aTest前缀对应的命名空间URI,也就是http://tempuri.org/Test;
  • namespace-uri-for-prefix($input-prefix, /root)会根据输入XML中<root>元素的命名空间上下文,找到test前缀对应的URI,同样是http://tempuri.org/Test;
  • 两者的本地名都是a,所以比较结果为真,就能输出你想要的"Success"了。

另外这段代码还能处理无前缀的QName(也就是属于默认命名空间或无命名空间的情况),逻辑会自动适配。

如果是用XSLT 2.0及以上版本的话,事情会简单很多,因为原生支持resolve-QName函数,可以直接把字符串形式的QName解析成标准QName对象,然后直接对比:

<xsl:if test="resolve-QName(/root/@name, /root) = QName('http://tempuri.org/Test', 'a')">
  Success
</xsl:if>

不过看你的示例用的是XSLT 1.0,所以上面的手动拆分方案更适合你。

备注:内容来源于stack exchange,提问作者Christopher Kellett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:02:44