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

如何正确反序列化带有XML命名空间的SOAP字符串?

带命名空间的SOAP响应反序列化解决方案

首先要修正你提供的SOAP响应XML格式错误:

  • 闭合标签 <n0:ZcustomerMasterInfoResponse/> 应改为 </n0:ZcustomerMasterInfoResponse>
  • 闭合标签 </soap:Envelop /> 应改为 </soap-env:Envelope>

以下是针对不同语言的具体实现方案,核心是严格匹配命名空间URI(前缀如soap-env、n0不影响解析,只需URI一致):

C# 实现(XmlSerializer)

1. 定义对应实体类

using System.Xml.Serialization;

// SOAP信封类
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class SoapEnvelope
{
    [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public SoapHeader Header { get; set; }

    [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public SoapBody Body { get; set; }
}

public class SoapHeader { }

public class SoapBody
{
    [XmlElement(ElementName = "ZcustomerMasterInfoResponse", Namespace = "urn:sap-com:document:sap:soap:functions:mc-style")]
    public ZcustomerMasterInfoResponse Response { get; set; }
}

[XmlRoot(ElementName = "ZcustomerMasterInfoResponse", Namespace = "urn:sap-com:document:sap:soap:functions:mc-style")]
public class ZcustomerMasterInfoResponse
{
    [XmlElement(ElementName = "EOutput")]
    public EOutput EOutput { get; set; }
}

// 根据实际子标签扩展EOutput类
public class EOutput
{
    // 示例:如果有<CustomerId>标签,添加对应属性
    // public string CustomerId { get; set; }
}

2. 安全反序列化代码

using System.IO;
using System.Xml;
using System.Xml.Serialization;

var soapResponseXml = "你的SOAP响应XML字符串";

// 配置安全解析规则,防止XXE攻击
var settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.XmlResolver = null;

using (var reader = XmlReader.Create(new StringReader(soapResponseXml), settings))
{
    var serializer = new XmlSerializer(typeof(SoapEnvelope));
    var envelope = (SoapEnvelope)serializer.Deserialize(reader);
    
    // 读取目标数据
    var customerOutput = envelope.Body.Response.EOutput;
}

Java 实现(JAXB)

1. 定义对应实体类

import jakarta.xml.bind.annotation.*;

@XmlRootElement(namespace = "http://schemas.xmlsoap.org/soap/envelope/", name = "Envelope")
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapEnvelope {
    @XmlElement(namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapHeader Header;

    @XmlElement(namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapBody Body;

    // Getters and Setters
    public SoapHeader getHeader() { return Header; }
    public void setHeader(SoapHeader header) { Header = header; }
    public SoapBody getBody() { return Body; }
    public void setBody(SoapBody body) { Body = body; }
}

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapHeader { }

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapBody {
    @XmlElement(namespace = "urn:sap-com:document:sap:soap:functions:mc-style", name = "ZcustomerMasterInfoResponse")
    private ZcustomerMasterInfoResponse response;

    // Getters and Setters
    public ZcustomerMasterInfoResponse getResponse() { return response; }
    public void setResponse(ZcustomerMasterInfoResponse response) { this.response = response; }
}

@XmlRootElement(namespace = "urn:sap-com:document:sap:soap:functions:mc-style", name = "ZcustomerMasterInfoResponse")
@XmlAccessorType(XmlAccessType.FIELD)
public class ZcustomerMasterInfoResponse {
    @XmlElement(name = "EOutput")
    private EOutput eOutput;

    // Getters and Setters
    public EOutput getEOutput() { return eOutput; }
    public void setEOutput(EOutput eOutput) { this.eOutput = eOutput; }
}

// 根据实际子标签扩展EOutput类
@XmlAccessorType(XmlAccessType.FIELD)
public class EOutput {
    // 示例:添加对应子标签的属性
    // private String CustomerId;
}

2. 安全反序列化代码

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Unmarshaller;
import org.xml.sax.XMLReader;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLConstants;
import java.io.StringReader;

String soapResponseXml = "你的SOAP响应XML字符串";

// 配置安全解析,禁用外部实体防止XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
XMLReader xmlReader = spf.newSAXParser().getXMLReader();

JAXBContext context = JAXBContext.newInstance(SoapEnvelope.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setProperty("org.xml.sax.XMLReader", xmlReader);

SoapEnvelope envelope = (SoapEnvelope) unmarshaller.unmarshal(new StringReader(soapResponseXml));
ZcustomerMasterInfoResponse response = envelope.getBody().getResponse();
EOutput output = response.getEOutput();

通用注意事项

  • 优先通过WSDL自动生成实体类,避免手动编写注解时的命名空间匹配错误
  • 必须确保XML格式合法,闭合标签、命名空间声明无错误
  • 所有解析操作必须开启安全配置,禁用DTD和外部实体引入,防止XXE注入攻击

内容的提问来源于stack exchange,提问作者pilotguy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:35:36