【问题标题】:Best way to handle an XML as String将 XML 作为字符串处理的最佳方法
【发布时间】:2018-11-28 23:14:17
【问题描述】:

我收到来自 Web 请求的响应作为实际上是 XML 的字符串,并且根据我发送的请求,此响应可能会有所不同。它 可以是带有 Success 节点或 Error 节点的 XML。

在我的代码中处理此问题的最佳方法是什么?
我可以把这个String作为一个对象来访问响应的每个节点吗?

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns1:myService xmlns:ns1="http://site.de/alpm">
         <ns1:Response>
               <ns1:OrganisationData>
                  <ns1:ClientId>myID</ns1:ClientId>
                  <ns1:UserId>service</ns1:UserId>
                  <ns1:Pass>myPass</ns1:Pass>
               </ns1:OrganisationData>
               <ns1:TransactionData>
                  <ns1:TrxId>tg0rta1a1-6fh-hfh5-ryyb-ryyt56</ns1:CSDBTrxId>
                  <ns1:TimeOfProcessing>2018-11-28T13:09:41.179Z</ns1:TimeOfProcessing>
               </ns1:TransactionData>          
            <ns1:Error>
               <ns1:ReturnCode>lpt-978-jh</ns1:ReturnCode>
               <ns1:Description>my description</ns1:Description>
            </ns1:Error>
         </ns1:Response>
      </ns1:myService>
   </soap:Body>
</soap:Envelope>

更改的是&lt;ns1:Error&gt;&lt;/ns1:Error&gt;,如果成功,它将是一个新标签。

如何在我的代码中处理这个问题。不要忘记我将其作为字符串接收?这是代码,字符串是“myResult”:

using (var webResponse = soapRequest.EndGetResponse(asyncResult))
{
    string myResult;
    var responseStream = webResponse.GetResponseStream();
    if (responseStream == null)
    {
        return null;
    }
    using (var reader = new StreamReader(responseStream))
    {
        myResult = reader.ReadToEnd();
    }
}

【问题讨论】:

  • 这可能会有所帮助,但我如何控制和检查标签是否存在 或成功标签?
  • 使字段可选 - 可以为空。

标签: c# xml-serialization


【解决方案1】:

您可以包含您期望的所有可能属性(以防您只会在“Error”和“NewTag”之间切换)并继续正常解析请求。

作为一个关于你的班级的例子:

public class Response
{
    [XmlElement("OrganisationData")] 
    public OrganisationData OrganisationData { get; set; }

    [XmlElement("TransactionData")] 
    public TransactionData TransactionData { get; set; }

    [XmlElement("Error")] 
    public Error Error { get; set; }

    [XmlElement("NewTag")] 
    public NewTag NewTag { get; set; }
}

现在您只需在反序列化 XML 字符串后检查“Error”或“NewTag”是否为空,并根据需要处理每种情况:

using (var webResponse = soapRequest.EndGetResponse(asyncResult))
{
    string myResult;
    var responseStream = webResponse.GetResponseStream();
    if (responseStream == null)
    {
        return null;
    }
    using (var reader = new StreamReader(responseStream))
    {
        myResult = reader.ReadToEnd();
    }
    var deserializedResult = YourDeserializationLogic(myResult);
    if(deserializedResult != null && deserializedResult.Error != null)
    {
       //Do your error handling Logic
    }
    else if(deserializedResult != null && deserializedResult.NewTag != null)
    {
       //Do your post success logic
    }
}

注意:我已经使用 XmlSerializer 测试了这个概念

【讨论】:

  • 该方法应该是什么? “你的反序列化逻辑”??在那个类中,我将无法添加 [XmlRoot(":myService" ...因为此值可能会根据我得到响应的服务而改变。例如,它必须是 [XmlElement("nsl:Error" )] 命名空间没有?
  • "YourDeserializationLogic" 是该方法应该具有将 XML 字符串反序列化为对象的代码,我没有包括它,因为它不是问题的核心。同样在您的问题中,您表示将更改的节点是错误节点,而不是整个 XML,因此如果整个 XML 将要更改,这是另一回事。至于必须包含命名空间,我认为它不是强制性的,我已经测试了我提供的不包含命名空间的解决方案,并且它可以正常工作。
  • 为了避免所有这些,您可以简单地搜索字符串是否包含错误标记或您需要查找的任何其他标记。例如:'if(myResult.Contains(""){ //做一些事情}'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 2013-11-27
  • 2010-10-10
  • 2010-12-03
  • 1970-01-01
相关资源
最近更新 更多