0

I know there is a lot of content regarding deserialization of xml files, but I have not found a solution so far. My XML looks like this

<Data>
    <Products>
        <Product name="product1" brand="brand1">
            <ProductValues>
                <ProductValue name="price" value="100"/> 
                <ProductValue name="stock" value="23"/>
            </ProductValues>
        </Product>
        <Product name="product2" brand="brand1">
            <ProductValues>
                <ProductValue name="price" value="100"/> 
                <ProductValue name="stock" value="23"/>
            </ProductValues>
        </Product>
        <Product name="product2" brand="brand1">
            <ProductValues>
                <ProductValue name="price" value="100"/> 
                <ProductValue name="stock" value="23"/>
            </ProductValues>
        </Product>
    </Products>

    ... <!-- And more products -->

</Data>

I have a Product and ProductValue class where the corresponding fields are marked as XmlAttribute

public class Product
{
    [XmlAttribute]
    public string name;
    [XmlAttribute]
    public string brand;
    public ProductValue[] ProductValues

    ... 
}

Everything works find, if I create a new class, which is called Data and has a field public Product[] products and I deserialize like this

XmlSerializer serializer = new XmlSerializer(typeof(Data));
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    Data data = (Data)serializer.Deserialize(stream);
}

I dont want to create an extra class for this and also not an extra field like here but only instanitate the serializer with an array type XmlSerializer serializer = new XmlSerializer(typeof(Product[])); to receive a local Product[]. But if I do so, I get the error <Data xmlns="> was not expected

link
  • 491
  • 1
  • 4
  • 13

2 Answers2

2

As @Rand Random pointed out a possible dublicate, I looked at that question and finally git it working combining this and this.

XmlReader reader = XmlReader.Create(path);
reader.MoveToContent();
reader.ReadToDescendant("Products");
XmlSerializer serializer = new XmlSerializer(typeof(Product[]), new XmlRootAttribute() { ElementName = "Products" });

var products = (Product[])serializer.Deserialize(reader);
link
  • 491
  • 1
  • 4
  • 13
0

Using Xml Linq :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            List<Product> products = doc.Descendants("Product").Select(x => new Product() {
                name = (string)x.Attribute("name"),
                brand = (string)x.Attribute("brand"),
                ProductValues = x.Descendants("ProductValue")
                    .GroupBy(y => (string)y.Attribute("name"), z => (string)z.Attribute("value"))
                    .ToDictionary(y => y.Key, z => z.FirstOrDefault())
            }).ToList();

        }
    }
    public class Product
    {
        public string name { get; set; }
        public string brand { get; set; }
        public Dictionary<string, string> ProductValues { get; set; }
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20