【问题标题】:Convert response stream to XML将响应流转换为 XML
【发布时间】:2019-08-08 14:03:15
【问题描述】:

我向演示 API 发送了 XML 帖子,响应以 XML 流的形式返回,如下所示:

API=3CProductData&XML=%3CProductData+Name%3D%22NameTest%22%3E%0D%0A++%3CId%3EXXXXXXXXX%3C%2FId%3E%0D%0A%3C%2FProductData%3E

我猜这就是流的样子,我的目标是获取该响应并将其存储在一个新的 ProductData 对象中,这是我目前所做的:

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    if (response.StatusCode == HttpStatusCode.OK)
    {
        // as an xml: deserialise into your own object or parse as you wish
        StreamReader respStream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);
        string receivedResponse = respStream.ReadToEnd();

        XmlSerializer x = new XmlSerializer(typeof(ProductData));

        ProductData product = (ProductData) x.Deserialize(new StringReader(receivedResponse));
        Console.WriteLine("Node1: " + product.Id.ToString());
        Console.WriteLine("Node2: " + product.Name);
        Console.ReadKey();
    }

错误返回 System.InvalidOperationException:“XML 文档 (0, 0) 中存在错误。” XmlException: 缺少根元素。

【问题讨论】:

  • 那是您的实际响应正文吗?还是来自查询字符串的数据?
  • 它的查询字符串也不应该是响应
  • @Jesse de Wit 我还定制了响应给我一个 XML 但仍然是同样的问题?
  • 那是一些糟糕的 XML。 Name 节点不会自行关闭。恐怕您将不得不手动处理此响应。
  • 查询字符串是(请求的)url 的一部分。 http 响应消息由状态码、标头和响应正文组成。在此处发布状态代码和响应正文,我们可能会提供帮助。 (将响应正文作为字符串读取并在调试器中检查)

标签: c# xml rest stream


【解决方案1】:

这里有两种不同的解决方案。

    public ProductData TestFunction()
    {
        ProductData result = new ProductData();

        string apiResponse = "API=3CProductData&XML=%3CProductData+Name%3D%22NameTest%22%3E%0D%0A++%3CId%3EXXXXXXXXX%3C%2FId%3E%0D%0A%3C%2FProductData%3E";
        string xml = HttpUtility.UrlDecode(apiResponse.Substring(apiResponse.IndexOf("XML=") + 4));
        XmlDocument document = new XmlDocument();
        document.LoadXml(xml);

        XmlNode newNode = document.DocumentElement;

        // Name is actually an attribute on the ProductData
        result.Name = ((XmlAttribute)newNode.Attributes["Name"]).InnerText;

        // Id is an actual node
        result.ID = ((XmlNode)newNode.FirstChild).InnerText;


        using (TextReader reader = new StringReader(xml))
        {
            var serializer = new XmlSerializer(typeof(ProductData));
            result = (ProductData)serializer.Deserialize(reader);
        }

        return result;
    }

[Serializable]
[XmlRoot("ProductData")]
public class ProductData
{
    [XmlElement("Id")]
    public string ID { get; set; }

    [XmlAttribute("Name")]
    public string Name { get; set; }

}

这段代码有一个非常脆弱的部分,我没有花很多时间尝试处理它。在我看来,XML 的格式并不是很好,因此您将不得不在XML= 之后添加子字符串,这就是我在其末尾添加 +4 的原因。可能是一种更流畅的方法,但问题仍然在于转换 XML。由于 XML 非常简单,您可以通过 SelectSingleNode 定位值。如果你想走 StreamReader 路线,你需要确保你的类/属性设置了属性(即 [XmlRoot("Productdata")])

【讨论】:

  • 好的,当我这样做时,它返回“缺少根元素”。任何建议
  • 你能用我的实现发布你的更新代码吗?
【解决方案2】:

您必须删除字符串中的 API=3CProductData&XML= 部分,然后解码您的部分 XML

看看这个code工作:

string strRegex = @"<ProductData Name=""NameTest"">\r\n  <Id>XXXXXXXXX</Id>\r\n</ProductData>";
ProductData result = null;
using (TextReader reader = new StringReader(strRegex))
{
    var serializer = new XmlSerializer(typeof(ProductData));
    result = (ProductData)serializer.Deserialize(reader);
}

【讨论】:

  • 我无法控制流和它的样子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 2020-10-22
  • 2019-06-21
相关资源
最近更新 更多