将响应流转换为XML

时间:2019-08-08 14:03:15

标签: c# xml rest stream

我向演示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:根元素丢失。

2 个答案:

答案 0 :(得分:0)

您必须删除字符串中的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);
}

答案 1 :(得分:0)

这是两种不同的解决方案。

    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”)])