【问题标题】:how to ignore soap stuff on deserializing xml to object?如何在将 xml 反序列化为对象时忽略肥皂内容?
【发布时间】:2013-12-09 18:47:07
【问题描述】:

当我得到一个 xml 时,我需要将它反序列化为一个特定的对象,并通过 web 服务方法中的参数传递它。

代码:

 var document = new XmlDocument();
 document.Load(@"C:\Desktop\CteWebservice.xml");
 var serializer = new XmlSerializer(typeof(OCTE));
 var octe = (OCTE) serializer.Deserialize(new StringReader(document.OuterXml));

 serviceClient.InsertOCTE(octe);

但是当我尝试反序列化时,我得到一个错误提示

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" > was not expected.

我需要忽略信封标签和其他 SOAP 内容。 我该怎么做?

xml文件:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:ns="http://192.168.1.180:8085/">
 <soapenv:Header/>
 <soapenv:Body>
  <ns:INCLUIRCONHECIMENTOFRETESAIDA>
     <ns:CONHECIMENTOFRETE>
        <ns:CSTICMS></ns:CSTICMS>
     </ns:CONHECIMENTOFRETE>
  </ns:INCLUIRCONHECIMENTOFRETESAIDA>
<soapenv:Body>

测试代码:

XNamespace soap = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace m = "http://192.168.1.180:8085/"; 
var soapBody = xdoc.Descendants(soap + "Body").First().FirstNode;

var serializer =  new XmlSerializer(typeof(OCTE));
var responseObj = (OCTE)serializer.Deserialize(soapBody.CreateReader());

soap Body 获取 &lt;ns:INCLUIRCONHECIMENTOFRETESAIDA&gt; 以及我需要的所有信息。但是当我将其反序列化为 responseObj 时,我将所有值都设为 null。

【问题讨论】:

  • 使用XDocument 并执行document.Descendant("OCTE")? (或任何根名称应该是)
  • 后代,不确定我是否可以在 XmlDocument 类中找到此成员。
  • 对,我把它和XDocument 混淆了。你可以改用那个类吗?不管怎样,我确信有一种方法可以将 XML 树向下导航到您的正文的值。
  • 我可以使用,但是使用 Descendant 我得到一个 IENumerable 而不是一个 OCTE 对象

标签: c# xml xml-serialization


【解决方案1】:

我没有足够的细节来为你填写命名空间和元素名称,但是使用W3C's example SOAP response,以下代码和类会反序列化对象:

var xdoc = XDocument.Load(@"C:\Desktop\CteWebservice.xml");
XNamespace soap = "http://www.w3.org/2001/12/soap-envelope";
XNamespace m = "http://www.example.org/stock";
var responseXml = xdoc.Element(soap + "Envelope").Element(soap + "Body")
                      .Element(m + "GetStockPriceResponse");

var serializer = new XmlSerializer(typeof(GetStockPriceResponse));
var responseObj =
      (GetStockPriceResponse)serializer.Deserialize(responseXml.CreateReader());


[XmlRoot("GetStockPriceResponse", Namespace="http://www.example.org/stock")]
public class GetStockPriceResponse
{
    public decimal Price { get; set; }
}

你可以对你的OCTE 类做同样的事情。

[XmlRoot("INCLUIRCONHECIMENTOFRETESAIDA",Namespace="http://192.168.1.180:8085/")]
public class OCTE
{
    // with property mapping to CONHECIMENTOFRETE, etc.
}

【讨论】:

  • 对不起,我不明白那是什么反应。网络服务不返回任何响应。我将我的 xml 的一些重要部分放在 OP 中。谢谢
  • @ggui 响应对应于您拥有的任何反映 INCLUIRCONHECIMENTOFRETESAIDA 的类。我假设这是 OCTE,并添加了代码来显示您需要在其上放置什么样的属性,以便序列化程序了解它是什么。
  • 是的,它是 OCTE 类。我获取了 octe.xml 文件的信息,然后将其解压缩为 OCTE 对象,然后作为参数发送到 Web 服务。生病试试你的解决方案。谢谢!
  • 好的,我明白了。现在我可以只为我的 OCTE 对象获取 xml 的“重要”部分。但是当我反序列化它时,我在 responseObj 上得到所有值 null。
  • @ggui 您可能需要在属性中包含 XmlElementAttributes 的名称和命名空间(以便序列化程序知道如何将 XML 映射到您的属性)。
猜你喜欢
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 2016-11-21
  • 2016-01-22
  • 1970-01-01
  • 2017-08-20
相关资源
最近更新 更多