使用XSLT为SOAP消息添加xmlns命名空间属性异常排查
问题解决:SOAP消息xsd前缀未定义异常及XSLT命名空间声明错误
问题根源
你的XSLT代码错误地将xmlns当作普通属性命名空间使用,导致处理器自动生成xp_0这类未知前缀,无法正确生成xmlns:xsd和xmlns:xsi命名空间声明。原代码中<xsl:attribute name="xsd" namespace="xmlns">的写法完全不符合命名空间声明规范。
正确解决方案
方案1:XSLT 1.0 兼容写法
直接构造xmlns:xsd和xmlns:xsi属性(这类命名空间声明属性本身不属于任何命名空间):
<!-- 用精准匹配替换原contains写法,避免误匹配其他节点 --> <xsl:template match="//*[local-name()='FaultDetails' and namespace-uri()='你的sys命名空间URI']"> <xsl:copy> <!-- 直接创建命名空间声明属性 --> <xsl:attribute name="xmlns:xsd">http://www.w3.org/2001/XMLSchema</xsl:attribute> <xsl:attribute name="xmlns:xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute> <!-- 复制原节点的所有属性和子节点 --> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template>
如果你的XSLT样式表已经声明了sys前缀对应的命名空间(比如<xsl:stylesheet ... xmlns:sys="sys的命名空间URI">),可以把match表达式简化为match="sys:FaultDetails",更直观。
方案2:XSLT 2.0+ 规范写法
使用xsl:namespace指令专门创建命名空间声明,更符合XSLT规范:
<!-- 需在样式表根节点声明sys前缀:xmlns:sys="sys的命名空间URI" --> <xsl:template match="sys:FaultDetails"> <xsl:copy> <xsl:namespace name="xsd" select="'http://www.w3.org/2001/XMLSchema'"/> <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'"/> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template>
关键说明
- 命名空间声明属性(如
xmlns:xsd)不属于任何命名空间,因此不能给xsl:attribute指定namespace="xmlns",这是原代码出错的核心原因。 - 原match表达式
contains(name(),'sys:FaultDetails')不够严谨,可能匹配到名称包含该字符串的其他节点,建议改用精准的前缀+本地名或命名空间URI+本地名匹配。
内容的提问来源于stack exchange,提问作者idvr
相关产品推荐
相关产品推荐

