C# Разбор XML в разные списки - PullRequest
2 голосов
/ 30 января 2020

У меня проблема. В моем приложении 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, поэтому lstImages имеет счет 9, потому что 5 из альбомов и 4 из <Images>

Вот мой 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();
}

Как это исправить?

Ответы [ 2 ]

4 голосов
/ 30 января 2020

Честно говоря, это работа для 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 в буфер обмена и отредактируйте => вставьте special => paste xml как классы

(существуют также сайты / инструменты, которые позволяют преобразовывать код xml в c# различного качества - например, https://xmltocsharp.azurewebsites.net/, но учтите, что это не очень хорошо работает с массивами и т. Д. c)

0 голосов
/ 30 января 2020

Попробуйте использовать xPath.

Что-то вроде

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

и

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