【问题标题】:C# Parse XML to different listsC# 将 XML 解析为不同的列表
【发布时间】:2020-01-30 18:48:30
【问题描述】:

我有问题。 在我的 Xamarin Forms 应用程序中,我对我的网页进行网络调用,我在其中收集 XML 以在应用程序中使用。我将 XML 解析为 3 个不同的列表。

  1. 专辑
  2. 图片
  3. 格式

现在这是我的 xml 的样子:

<Data>
    <Albums>
        <Album>
            <Image></Image>
            <Image></Image>
            <Image></Image>
        </Album>
        <Album>
            <Image></Image>
            <Image></Image>
        </Album>
    </Albums>
    <Images>
        <Image></Image>
        <Image></Image>
        <Image></Image>
        <Image></Image>
    </Images>
    <Formats>
        <Format></Format>
        <Format></Format>
    </Formats>
</Data>

解析后,想要的结果是:

lstAlbums.Count = 2
lstImages.Count = 4
lstFormats.Count = 2

但显然它会计算完整 xml 中的所有 &lt;&gt; 标签,因此 lstImages 的计数为 9,因为专辑中有 5 个,&lt;Images&gt; 中有 4 个

这是我的 C# 代码:

if (!string.IsNullOrEmpty(xmlString))
{
    doc = XDocument.Parse(xmlString);
}

//Check if xml has any elements 
if (!string.IsNullOrEmpty(xmlString) && doc.Root.Elements().Any())
{
    App.lstAlbums = doc.Descendants("Albums").Descendants("Album").Select(d =>
    new Album
    {
        Id = Convert.ToInt32(d.Element("Id").Value),
        Name = d.Element("Name").Value,
        Images = doc.Descendants("Album").Descendants("Image").Select(a =>
            new myImage
            {
                Id = Convert.ToInt32(a.Element("Id").Value),
                Name = a.Element("Name").Value,
                Size = a.Element("Size").Value,
                Price = Convert.ToDecimal(a.Element("Price").Value)
            }).ToList(),
        Prijs = Convert.ToDecimal(d.Element("Price").Value)
    }).ToList();

    App.lstImages = doc.Descendants("Images").Descendants("Image").Select(e =>
    new myImage
    {
        Id = Convert.ToInt32(e.Element("Id").Value),
        Name = e.Element("Name").Value
    }).ToList();

    App.lstFormats = doc.Descendants("Formats").Descendants("Format").Select(e =>
    new Format
    {
        Id = Convert.ToInt32(e.Element("Id").Value),
        Size = e.Element("Size").Value,
        Price = Convert.ToDecimal(e.Element("Price").Value)
    }).ToList();
}

我该如何解决这个问题?

【问题讨论】:

  • Descendents 方法是递归的;如果您只打算查看一个级别,请改用Elements,但坦率地说,这看起来很适合XmlSerializer,而不是手动解析。
  • 您能否为我的其中一个列表(例如专辑)提供示例代码?
  • 我要反序列化这个,手动解析只是很多已经存在的代码。

标签: c# xml parsing xamarin.forms


【解决方案1】:

坦率地说,这是XmlSerializer 的工作。以下应该有效:

[XmlRoot("Data")]
public class MyData {
    [XmlArray("Albums")]
    [XmlArrayItem("Album")]
    public List<Album> Albums {get;} = new List<Album>();

    [XmlArray("Images")]
    [XmlArrayItem("Image")]
    public List<string> Images {get;} = new List<string>();

    [XmlArray("Formats")]
    [XmlArrayItem("Format")]
    public List<string> Formats {get;} = new List<string>();
}

public class Album {
    [XmlElement("Image")]
    public List<string> Images {get;} = new List<string>();
}

用法:

var serializer = new XmlSerializer(typeof(MyData));
var obj = (MyData)serializer.Deserialize(source);

如果你真正的 xml 更复杂:只需将 xml 复制到剪贴板,然后编辑 => 粘贴特殊 => 将 xml 粘贴为类

(还有一些站点/工具可让您将 xml 转换为 c# 代码,质量参差不齐 - 例如 https://xmltocsharp.azurewebsites.net/,但请注意,这在数组等方面做得并不好)

【讨论】:

  • 好的,我添加了您的代码,但它在此行崩溃:var serializer = new XmlSerializer(typeof(MyData)); 并出现错误:System.InvalidOperationException: 'There was an error reflecting type 'MyApp.Models.MyData'.'
  • @A.Vreeswijk 内部异常说什么?问题是什么通常很健谈
  • @A.Vreeswijk 也:在这里工作正常 - 您是否更改了可访问性? gist.github.com/mgravell/0180b1b46eb4388b3aa733c5aee1afd3
  • 我想我为什么会收到这个错误。我做了一些更改,因为您的代码对我的代码不完整。我需要添加类:图像和格式。您已经添加了相册。您能否使用以下类更新您的代码,以便我可以看到我做错了什么:Album =&gt; Id, Name, List&lt;Image&gt; Images --- Image =&gt; Id, Name, Price --- Format =&gt; Id, Size
【解决方案2】:

尝试使用 xPath。

有点像

(IEnumerable)doc.XPathEvaluate("//Albums/Album")

(IEnumerable)doc.XPathEvaluate("//Images/Image")

【讨论】:

  • 我怎样才能将它分配给我的列表?
  • 遍历 IEnumerable(或从中选择)。您需要将 IEnumerable 中的每个项目转换为 XElement(因为您了解 XML 结构是什么)。然后从 XElement 中提取属性。 XElement 具有 Attribute 和 Attributes 方法。 XmlSerializer 可能是一个更好的选择,但这应该是您已经拥有的代码的简单交换。
猜你喜欢
  • 1970-01-01
  • 2014-12-25
  • 2018-08-12
  • 2015-04-13
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多