如何用数组反序列化 XML 文件?

How to deserialize XML file with Array?

如果元素后面有动态数字,我可以知道如何使用 C# 序列化和反序列化吗? Block1 和 Block2 将根据块计数动态变化。

<DefectList>
    <BlockCount>2</BlockCount>
    <Block1>
    </Block1>
    <Block2>
    </Block2>
</DefectList>

谢谢。

        public static T Deserialize<T>(this T Value, string xmlPath)
    {
        T ret = default(T);

        if (!string.IsNullOrEmpty(xmlPath))
        {
            var serializer = new XmlSerializer(typeof(T));
            using (var tw = new FileStream(xmlPath, FileMode.Open))
            {
                ret = (T)serializer.Deserialize(tw);
                tw.Close();
            }
        }
        return ret;
    }

我正在尝试使用此方法进行反序列化。我的模型如下

   public class DefectList
{
    [XmlElement("DefectList")]
    public string DefectList{ get; set; }

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

    [XmlElement]
    public ObservableCollection<Block> Block { get; set; }
}

好吧,假设你有这两个功能:

Block DeserializeBlock(XElement xe) => ...
XElement SerializeBlock(Block block, int x) => ...

你有这个 source:

Block[] source = ...

然后序列化是这样的:

XDocument xd =
    new XDocument(
        new XElement("BlockCount", source.Length),
        source.Select((x, n) => SerializeBlock(x, n + 1)));

反序列化是这样的:

Block[] output =
    Enumerable
        .Range(1, (int)xd.Root.Element("BlockCount"))
        .Select(x => DeserializeBlock(xd.Root.Element($"Block{x}")))
        .ToArray();

使用自定义 xml 序列化器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.IO;
namespace ConsoleApplication29
{
    class Program
    {
        const string INPUT_FILENAME = @"c:\temp\test.xml";
        const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DefectList));
            XmlReader reader = XmlReader.Create(INPUT_FILENAME);

            DefectList defectList = (DefectList)serializer.Deserialize(reader);

            
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME,settings);
            serializer.Serialize(writer,defectList);
        }
    }
    public class DefectList : IXmlSerializable
    {
        XmlSerializer blockSerializer = new XmlSerializer(typeof(Block));
        [XmlElement("DefectList")]
        public string defectList { get; set; }

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

        [XmlElement]
        public List<Block> Blocks { get; set; }

        public void WriteXml(XmlWriter writer)
        {
            //XElement defectList = new XElement("DefectList");
            //defectList.Add(new XElement("BlockCount", Blocks.Count));
            writer.WriteElementString("BlockCount", Blocks.Count.ToString());
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", null);
            for (int i = 0; i < Blocks.Count; i++)
            {
                StringWriter sWriter = new StringWriter();
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;
                settings.Indent = true;
                XmlWriter xWriter = XmlWriter.Create(sWriter, settings);
                
                blockSerializer.Serialize(xWriter, Blocks[i], ns);
                string elementStr = sWriter.ToString();
                XElement tempBlock = XElement.Parse(elementStr);
                string childElementsStr = string.Join("",tempBlock.Elements().Select(x => x.ToString()));
                writer.WriteStartElement("Block" + (i + 1));
                writer.WriteRaw(childElementsStr);
                writer.WriteEndElement();
                //defectList.Add(new XElement("Block" + (i + 1), tempBlock.Elements()));
            }
            //writer.WriteRaw(string.Join("\n",defectList.Elements().Select(x => x.ToString())));
        }

        public void ReadXml(XmlReader reader)
        {
            XElement defectList = (XElement)XElement.ReadFrom(reader);
            BlockCount = (int)defectList.Element("BlockCount");
            List<XElement> blocks = defectList.Elements().Where(x => (x.Name != "BlockCount") && (x.Name.LocalName.StartsWith("Block"))).ToList();
            foreach (XElement block in blocks)
            {
                XElement tempBlock = new XElement("Block", block);
                StringReader sReader = new StringReader(tempBlock.ToString());
                if (Blocks == null) Blocks = new List<Block>();
                Blocks.Add((Block)blockSerializer.Deserialize(XmlReader.Create(sReader)));
            }
        }

        public XmlSchema GetSchema()
        {
            return (null);
        }
    }
    public class Block
    {
    }
}