如何反序列化 C# 对象中复杂的 XML 格式并读取它以使用其值?
Posted
技术标签:
【中文标题】如何反序列化 C# 对象中复杂的 XML 格式并读取它以使用其值?【英文标题】:How to deserialize a difficult XML format in C# object and read it in order to use its values? 【发布时间】:2021-01-30 18:24:20 【问题描述】:我有一个非常难格式化的 XML 文档,我想阅读它并使用它的参数。
这是我要反序列化的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<APIResponse xmlns="https://testwebservice.com/">
<Result>Api Result Message</Result>
</APIResponse>
</soap:Body>
</soap:Envelope>
我已经尝试了一些在其他问题中找到的代码示例
APIResponse envelopeClass = new APIResponse();
XmlSerializer serializer = new XmlSerializer(typeof(APIResponse), new XmlRootAttribute("Envelope"));
StringReader stringReader = new StringReader(xmlString);
envelopeClass = (APIResponse)serializer.Deserialize(stringReader);
但到目前为止没有任何帮助,因为我收到这样的错误:
System.InvalidOperationException: 'XML 文档 (1, 42) 中存在错误。' 内部异常 InvalidOperationException:
不是预期的。
这些是迄今为止我在 Visual Studio 中通过 选择性粘贴 按钮使用的类。
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)]
public partial class Envelope
public EnvelopeBody bodyField get; set;
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody
[System.Xml.Serialization.XmlElementAttribute(Namespace = "https://testwebservice.com/")]
public APIResponse aPIResponseField get; set;
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="https://testwebservice.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="https://testwebservice.com/", IsNullable=false)]
public partial class APIResponse
public string resultField get; set;
尽管如此,我仍然不明白为什么会出现上述错误,但我想指出我还没有完全理解这一切是如何工作的。 无论如何,如果有人可以提供帮助,我将不胜感激。
请告诉我哪些是我应该在这个 XML 格式文档中使用的正确类以及如何反序列化它。
【问题讨论】:
Xml 序列化很难调试。我通常注释掉 c# 类的部分以查找错误。如果 XML 中存在标签并且没有 c# 类属性,则不会生成错误。我通常首先在 c# 类中注释掉根类中的所有属性,以确保 xml 没有错误。然后移除 cmets,直到我确定问题所在。 【参考方案1】:您所称的“困难 XML 格式”实际上是标准 SOAP (Simple Object Access Protocol) 消息。 SOAP 被用作基于 XML 的 Web 服务的通信协议,它首先让您想到您可以为 Web 服务添加一个服务引用,您可以从其中获取此 XML 内容。如果您从 Web 资源中获取此 XML 内容,请尝试将其添加为服务参考。
如果没有,并且您刚刚以某种方式结束了此 XML 内容,尽管有一些示例说明如何通过解析并仅序列化其中的一部分从 xml 中获取响应对象,这就是我的假设是一种更精细、更安全的方式来实现它。
添加 NuGet 引用:Microsoft.Web.Services3
将类ApiResponse更改如下(将名称resultField改为Result)
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "https://testwebservice.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "https://testwebservice.com/", IsNullable = false)]
public partial class APIResponse
public string Result get; set;
然后使用 SoapEnvelope 类及其方法获取ApiResponse
对象,例如:
using Microsoft.Web.Services3;
. . .
. . .
SoapEnvelope envelope = new SoapEnvelope();
envelope.LoadXml(xmlString);
APIResponse apiResponse = (APIResponse)envelope.GetBodyObject(typeof(APIResponse));
. . .
. . .
【讨论】:
我可以在不使用 Microsoft.WebServices3 包的情况下使用这些类吗? 因为它有依赖问题 我认为不是。您可以检查其他响应(this)(https://***.com/questions/6838504/parsing-a-soap-response-with-c-sharp), ot [this 了解 XML 的执行方式。以上是关于如何反序列化 C# 对象中复杂的 XML 格式并读取它以使用其值?的主要内容,如果未能解决你的问题,请参考以下文章