簡體   English   中英

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

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

我遇到的情況是,有多個xml文件都共享相同的根元素“ GroceryBag”,但這些文件中的子元素可能是任何類型或數量。 我已經知道所有可能的子元素類型。

我的具體問題是如何用來自所有xml文件的組合數據填充“ AllBagsEver” ...更好。 下面的代碼不是我的實際項目代碼,但是我已經寫了它來說明我的觀點。 最終的游戲是使用“ GroceryBag”上的每個對象列表作為DataGridView的數據源。

另外,Im使用的xml文件屬於另一個程序,因此不能更改xml結構。 另一方面,我的實現很糟糕,所以這里要改變它,加油。

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;
        }
    }
}

以下是一些要合並的單個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>

以下是使用Linq To XML和列表集合的解決方案。

現在,您將所有元素都包含在列表中。 您只需要運行一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM