简体   繁体   English

使用C#将具有相同根但将子元素不同的多个xml文件反序列化为一个

[英]Deserialize multiple xml files with the same root but varying child elements into one with c#

I have a situation where there are multiple xml files that all share the same root element 'GroceryBag' but the child elements in these files may be of any type or quantity. 我遇到的情况是,有多个xml文件都共享相同的根元素“ GroceryBag”,但这些文件中的子元素可能是任何类型或数量。 All the possible child element types are already known by me. 我已经知道所有可能的子元素类型。

My specific question is how can I populate my 'AllBagsEver' with the combined data from all the xml files... better. 我的具体问题是如何用来自所有xml文件的组合数据填充“ AllBagsEver” ...更好。 The code below is not my actual project code but I have written it to illustrate my point. 下面的代码不是我的实际项目代码,但是我已经写了它来说明我的观点。 The end game here is using each object list on 'GroceryBag' as a DataSource for DataGridView. 最终的游戏是使用“ GroceryBag”上的每个对象列表作为DataGridView的数据源。

Also, the xml files Im working with belong to another program so changing the xml structure is not an option. 另外,Im使用的xml文件属于另一个程序,因此不能更改xml结构。 On the other hand my implementation is terrible so heres to changing that, cheers. 另一方面,我的实现很糟糕,所以这里要改变它,加油。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;


namespace StackOverflow
{
    class Program
    {
        public static GroceryBag AllBagsEver = new GroceryBag();
        public static Random rng = new Random();

        static void Main(string[] args)
        {
            GoShopping();
            PopulateBigBag();
            string bagCount = 
                "Apples: " + AllBagsEver.Apples.Count + 
                "\nBreads: " + AllBagsEver.Breads.Count +
                "\nCheeses: " + AllBagsEver.Breads.Count +
                "\nMilks: " + AllBagsEver.Breads.Count +
                "\nChickens: " + AllBagsEver.Breads.Count;
            AllBagsEver.Serialize(Environment.CurrentDirectory, "MergedAll.xml");
            Console.WriteLine(bagCount);
            Console.ReadKey();
        }


        static void PopulateBigBag()
        {
            foreach (string file in Directory.EnumerateFiles(Environment.CurrentDirectory, "*.xml"))
            {
                GroceryBag tmp = GroceryBag.Deserialize(file);
                AllBagsEver.Apples.AddRange(tmp.Apples);
                AllBagsEver.Breads.AddRange(tmp.Breads);
                AllBagsEver.Cheeses.AddRange(tmp.Cheeses);
                AllBagsEver.Milks.AddRange(tmp.Milks);
                AllBagsEver.Chickens.AddRange(tmp.Chickens);
            }
        }


        static void GoShopping() //simulate variable data
        {
            GroceryBag tmpBag = new GroceryBag();
            if (rng.NextDouble() > 0.5)
            {
                Apple HoneyCrispApple = new Apple();
                HoneyCrispApple.Name = "HoneyCrisp";
                HoneyCrispApple.Price = 7;
                HoneyCrispApple.Weight = 1;
                tmpBag.Apples.Add(HoneyCrispApple);
            }
            if (rng.NextDouble() > 0.5)
            {
                Apple FujiApple = new Apple();
                FujiApple.Name = "Fuji";
                FujiApple.Price = 5;
                FujiApple.Weight = 1;
                tmpBag.Apples.Add(FujiApple);       
            }
            if (rng.NextDouble() > 0.5)
            {
                Bread BagelBread = new Bread();
                BagelBread.Name = "Bagel";
                BagelBread.Price = 3;
                BagelBread.Weight = 1;
                tmpBag.Breads.Add(BagelBread);
            }
            if (rng.NextDouble() > 0.5)
            {
                Bread CiabattaBread = new Bread();
                CiabattaBread.Name = "Ciabatta";
                CiabattaBread.Price = 10;
                CiabattaBread.Weight = 2;
                tmpBag.Breads.Add(CiabattaBread);
            }
            if (rng.NextDouble() > 0.5)
            {
                Cheese AbbotCheese = new Cheese();
                AbbotCheese.Name = "Abbot";
                AbbotCheese.Price = 4;
                AbbotCheese.Weight = 1;
                tmpBag.Cheeses.Add(AbbotCheese);
            }
            if (rng.NextDouble() > 0.5)
            {
                Cheese MaasdamCheese = new Cheese();
                MaasdamCheese.Name = "Maasdam";
                MaasdamCheese.Price = 4;
                MaasdamCheese.Weight = 1;
                tmpBag.Cheeses.Add(MaasdamCheese);
            }
            if (rng.NextDouble() > 0.5)
            {
                Milk VitaminDMilk = new Milk();
                VitaminDMilk.Name = "Vitamin D";
                VitaminDMilk.Price = 4;
                VitaminDMilk.Weight = 1;
                tmpBag.Milks.Add(VitaminDMilk);
            }

            string filename = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            tmpBag.Serialize(Environment.CurrentDirectory, filename);
        }
    }




    [Serializable, XmlRoot(ElementName = "GroceryBag")]
    public class GroceryBag //database 
    {
        [XmlElement("Apple")]
        public List<Apple> Apples { get; set; }

        [XmlElement("Bread")]
        public List<Bread> Breads { get; set; }

        [XmlElement("Cheese")]
        public List<Cheese> Cheeses { get; set; }

        [XmlElement("Milk")]
        public List<Milk> Milks { get; set; }

        [XmlElement("Chicken")]
        public List<Chicken> Chickens { get; set; }

        public GroceryBag()
        {
            Apples = new List<Apple>();
            Breads = new List<Bread>();
            Cheeses = new List<Cheese>();
            Milks = new List<Milk>();
            Chickens = new List<Chicken>();
        }

        public void Serialize(string path, string filename)
        {
            string writePath = path + "\\" + filename + ".xml";
            Console.WriteLine("Serializing to: " + writePath);
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            XmlSerializer xmlWriter = new XmlSerializer(typeof(GroceryBag));
            StreamWriter xmlStream = new StreamWriter(writePath);
            xmlWriter.Serialize(xmlStream, this);
            xmlStream.Close();
        }

        public static GroceryBag Deserialize(string filePath)
        {
            Console.WriteLine("Deserializing from " + filePath);
            TextReader txtReader = new StreamReader(filePath);
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(GroceryBag));
            GroceryBag bag = (GroceryBag)xmlSerializer.Deserialize(txtReader);
            txtReader.Close();
            return bag;
        }
    }


    [Serializable]
    [XmlType("Apple")]
    public class Apple
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlElement("Price")]
        public int Price { get; set; }

        [XmlElement("Weight")]
        public int Weight { get; set; }

        public Apple()
        {
            Name = "GenericApple";
            Price = 0;
            Weight = 0;
        }
    }


    [Serializable]
    [XmlType("Bread")]
    public class Bread
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlElement("Price")]
        public int Price { get; set; }

        [XmlElement("Weight")]
        public int Weight { get; set; }

        public Bread()
        {
            Name = "GenericBread";
            Price = 0;
            Weight = 0;
        }
    }


    [Serializable]
    [XmlType("Cheese")]
    public class Cheese
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlElement("Price")]
        public int Price { get; set; }

        [XmlElement("Weight")]
        public int Weight { get; set; }


        public Cheese()
        {
            Name = "GenericCheese";
            Price = 0;
            Weight = 0;
        }
    }


    [Serializable]
    [XmlType("Milk")]
    public class Milk
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlElement("Price")]
        public int Price { get; set; }

        [XmlElement("Weight")]
        public int Weight { get; set; }

        public Milk()
        {
            Name = "GenericMilk";
            Price = 0;
            Weight = 0;
        }
    }


    [Serializable]
    [XmlType("Chicken")]
    public class Chicken
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

        [XmlElement("Price")]
        public int Price { get; set; }

        [XmlElement("Weight")]
        public int Weight { get; set; }

        public Chicken()
        {
            Name = "GenericChicken";
            Price = 0;
            Weight = 0;
        }
    }
}

Here are some examples of what the individual xml files to merge look like. 以下是一些要合并的单个xml文件的示例。

<?xml version="1.0" encoding="utf-8"?>
<GroceryBag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Bread Name="Bagel">
    <Price>3</Price>
    <Weight>1</Weight>
  </Bread>
  <Cheese Name="Maasdam">
    <Price>4</Price>
    <Weight>1</Weight>
  </Cheese>
  <Milk Name="Vitamin D">
    <Price>4</Price>
    <Weight>1</Weight>
  </Milk>
</GroceryBag>



<?xml version="1.0" encoding="utf-8"?>
<GroceryBag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Apple Name="HoneyCrisp">
    <Price>7</Price>
    <Weight>1</Weight>
  </Apple>
  <Apple Name="Fuji">
    <Price>5</Price>
    <Weight>1</Weight>
  </Apple>
</GroceryBag>



<?xml version="1.0" encoding="utf-8"?>
<GroceryBag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Bread Name="Bagel">
    <Price>3</Price>
    <Weight>1</Weight>
  </Bread>
</GroceryBag>

Below is a solution using Linq To XML and List Collection. 以下是使用Linq To XML和列表集合的解决方案。

Now you have all the elements in a List. 现在,您将所有元素都包含在列表中。 you just need to run a foreach loop and add it to a separate xml object. 您只需要运行一个foreach循环并将其添加到单独的xml对象中。

  XDocument xdoc = XDocument.Load(@"C:\Users\max\Desktop\xml_answer\ConsoleApplication1\ConsoleApplication1\XMLFile1.xml");
        var content1 = from root in xdoc.Descendants("GroceryBag")
                      select root.Elements();
        var list = content1.ToList();

        XDocument xdoc1 = XDocument.Load(@"C:\Users\max\Desktop\xml_answer\ConsoleApplication1\ConsoleApplication1\XMLFile2.xml");
        var content2 = from root in xdoc.Descendants("GroceryBag")
                       select root.Elements();
        var list2 = content2.ToList();

        XDocument xdoc3 = XDocument.Load(@"C:\Users\max\Desktop\xml_answer\ConsoleApplication1\ConsoleApplication1\XMLFile3.xml");
        var content3 = from root in xdoc.Descendants("GroceryBag")
                       select root.Elements();
        var list3 = content3.ToList();

        list.AddRange(list2);
        list.AddRange(list3);
        var tot = list;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何用root反序列化Xml而不是多个相同类型的子元素 - How to deserialize Xml with root than multiple child elements of the same type 在C#中反序列化具有相同名称的多个XML元素 - Deserialize multiple XML elements with the same name in C# 使用c#中的子元素反序列化xml文件 - Deserialize a xml file with child elements in c# 用根元素,elemnt和子元素c#反序列化Xml文件 - Deserialize Xml file with root element, elemnts and child element c# 如何在C#中使用子元素反序列化XML? - How do I deserialize XML with child elements in C#? 当多个元素有一个孩子时,如何序列化/反序列化xml? - How to serialize/deserialize xml when multiple elements have one child? 使用多个根(xmlns)命名空间将XML文档反序列化为C#类 - Deserialize XML document to C# class, with multiple root (xmlns) namespaces 通过C#中的XmlSerializer类反序列化多个具有相同名称的XML元素 - Deserialize multiple XML elements with the same name through XmlSerializer class in C# 通过C#中的XmlSerializer类反序列化具有相同名称的多个但“不同”的XML元素 - Deserialize multiple but “different” XML elements with the same name through XmlSerializer class in C# 如何在具有相同类型的子节点的C#中反序列化XML - How to Deserialize XML in c# having child nodes of same type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM