从 XML 响应转换为列表

问题描述 投票:0回答:2
XElement Xml = null;
var apiResponse = response.Content.ReadAsStringAsync().Result;
Xml = Newtonsoft.Json.JsonConvert.DeserializeObject<XElement>(apiResponse);

上述代码的 XML 响应:

我在将

Images
XML 部分转换为列表时遇到错误, 我尝试了很多选择,请在下面提供建议:

<root>
  <Column1>
    <ID>2702</ID>
    <Desc>Failed</Desc>
    <Address>Florida</Address>
    <Date>2019-04-30T23:10:36.79</Date>
    <Images>
      <Image>
        <File>1-RRamos.PNG</File>
      </Image>
      <Image>
        <File>RRamos.PNG</File>
      </Image>
      <Image>
        <File>3-RRamos.PNG</File>
      </Image>
    </Images>
  </Column1>
</root>

尝试从 XML 转换为列表,如下所示:

public class objClass
{
    public string ID { get; set; }
    public string Desc { get; set; }
    public string Address { get; set; }
    public DateTime? Date { get; set; }

    //public string[] ImageFileNames { get; set; }

    public List<Images> FileName { get; set; }
}

public class Images
{
    public string File { get; set; }
}

List<objClass> list = Xml.Elements("ID").Select(sv => new objClass()
{
    ID = (string)sv.Element("ID"),
    Desc = (string)sv.Element("Desc"),
    Address = (string)sv.Element("Address"),
    Date = (DateTime?)sv.Element("Date"),
    //**,Images = (List)sv.Element("Images")**
}).ToList();
c# xml list .net-core xml-deserialization
2个回答
1
投票

您无法使用 Newtonsoft.Json 库从 XML 进行反序列化。

解决方案1:通过XPath将XML转换为列表

  1. 将 XML 字符串解析为

    XDocument

  2. 使用 XPath:“//root/Column1”,选择

    <Column1>
    元素。

using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml.XPath;

var apiResponse = await response.Content.ReadAsStringAsync();
XDocument @Xml = XDocument.Parse(apiResponse);
        
List<ObjClass> list = @Xml.XPathSelectElements("//root/Column1")
    .Select(sv => new ObjClass()
            {
                ID = (string)sv.Element("ID"),
                Desc = (string)sv.Element("Desc"),
                Address = (string)sv.Element("Address"),
                Date = (DateTime?)sv.Element("Date"),
                Images = sv.Element("Images")
                    .Elements("Image")
                    .Select(x => new Image
                            {
                                File = (string)x.Element("File")
                            })
                    .ToList()   
            })
    .ToList();

解决方案 2:反序列化 XML

这个答案会有点复杂,但工作原理与解决方案 1相同。

  1. apiResponse
    值写入
    MemoryStream

  2. 通过

    MemoryStream
    XmlSerializer
    反序列化为
    Root

  3. 提取

    root.Column
    并添加到
    list

[XmlRoot(ElementName = "root")]
public class Root
{
    [XmlElement("Column 1")]
    public ObjClass Column { get; set; }
}

public class ObjClass
{
    public string ID { get; set; }

    public string Desc { get; set; }

    public string Address { get; set; }

    public DateTime? Date { get; set; }

    [XmlArray]
    [XmlArrayItem(typeof(Image), ElementName = "Image")]
    public List<Image> Images { get; set; }
}

public class Image
{
    public string File { get; set; }
}
using System.Xml;
using System.Xml.Serialization;
using System.IO;

var apiResponse = await response.Content.ReadAsStringAsync();

using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
writer.Write(apiResponse);
writer.Flush();
stream.Position = 0;
        
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Root));      
        
Root root = (Root)xmlSerializer.Deserialize(stream);
List<ObjClass> list = new List<ObjClass>();
list.Add(root.Column);

关注:

  1. 使用
    await
    而不是
    Task<T>.Result
    ,因为
    Task<T>.Result
    会阻塞调用线程,直到它(任务)完成。使用
    await
    ,任务等待异步完成。参考:await Task 和 Task.Result 有什么区别?

0
投票
public class objClass
{
    public string ID { get; set; }
    public string Desc { get; set; }
    public string Address { get; set; }
    public DateTime? Date { get; set; }
    public string[] ImageFileNames { get; set; }
}

var list = Xml.Elements("root").Elements("Column1")
.Select(sv => new objClass()
{
    ID = (string)sv.Element("ID"),
    Desc = (string)sv.Element("Desc"),
    Address = (string)sv.Element("Address"),
    Date = (DateTime?)sv.Element("Date"),
    ImageFileNames = sv.Element("Images")
        .Elements("Image")
        .Select(i => (string)i.Element("File"))
        .ToArray(),
})
.ToList();
© www.soinside.com 2019 - 2024. All rights reserved.