移除XML中的SOAP信封:修复XSLT代码实现预期输出
移除XML中SOAP信封的XSLT解决方案
需要处理一份包含SOAP信封的XML,目标是移除SOAP信封部分,保留<Messages>节点及其内部所有内容,且代码需适配<Messages>内的任意字段和节点。现有XSLT代码未达到预期效果,具体信息如下:
输入XML
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <Messages xmlns="http://web.ui.com"> <result failed="0" scheduled="0" sent="1"> <Details limit="4" rem="2" type="ys"/> </result> </Messages> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
现有XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://web.ui.com" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/SOAP-ENV:Envelope"> <xsl:apply-templates select="SOAP-ENV:Body/*"/> </xsl:template> <xsl:template match="SOAP-ENV:Body"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="@*"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
预期输出
<?xml version="1.0" encoding="UTF-8"?> <Messages xmlns="http://web.ui.com"> <result failed="0" scheduled="0" sent="1"> <Details limit="4" rem="2" type="ys"/> </result> </Messages>
问题分析与修正方案
现有XSLT的问题在于:声明了默认命名空间xmlns="http://web.ui.com",导致复制<Messages>内部的<result>、<Details>等节点时,会自动给这些节点添加该命名空间,与预期输出不符。同时模板可以进一步简化。
修正后的XSLT代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" version="1.0"> <xsl:output method="xml" indent="yes"/> <!-- 匹配SOAP信封的Body节点,直接处理其子节点 --> <xsl:template match="/SOAP-ENV:Envelope/SOAP-ENV:Body"> <xsl:apply-templates/> </xsl:template> <!-- 匹配SOAP信封节点,不输出该节点 --> <xsl:template match="SOAP-ENV:Envelope"/> <!-- 身份模板:原样复制所有其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 移除了多余的默认命名空间声明,避免给非目标节点添加额外命名空间。
- 简化模板逻辑:直接匹配
SOAP-ENV:Body并处理其子节点,同时匹配SOAP-ENV:Envelope并忽略输出。 - 保留身份模板,确保
<Messages>节点及其内部所有内容(包括任意字段、子节点)都被原样复制,完全适配需求。
运行修正后的XSLT,即可得到符合预期的输出结果。
内容的提问来源于stack exchange,提问作者janardhan d
相关产品推荐
相关产品推荐

