0

may I know how to serialize and deserialize using C# if there have dynamic number behind of the element ? Block1 and Block2 will be dynamic based on the Block Count.

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

Thanks.

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

I'm trying to use this method to deserialize. and my model as below

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

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

    [XmlElement]
    public ObservableCollection<Block> Block { get; set; }
}
4
  • What have you tried so far? Where did you get stuck? Commented Jun 1, 2022 at 5:51
  • Using XmlSerializer can seductively lead you to the darkside. Commented Jun 2, 2022 at 3:49
  • @Enigmativity Is there any limitation on XmlSerializer? Commented Jun 2, 2022 at 4:26
  • @Ooi - Yes, it forces you to code your objects in a way which suits serialization - which then can conflict with other libraries you may use and it means that you might have to make some fields have accessibility that you don't want. It becomes an additional constraint that you might not need. When you roll your own you have full control of how it is implemented. Much easier for encapsulation and versioning. Commented Jun 2, 2022 at 6:13

2 Answers 2

2

Well, given you have these two functions:

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

And that you have this source:

Block[] source = ...

Then serialize is like this:

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

And Deserialize is like this:

Block[] output =
    Enumerable
        .Range(1, (int)xd.Root.Element("BlockCount"))
        .Select(x => DeserializeBlock(xd.Root.Element($"Block{x}")))
        .ToArray();
Sign up to request clarification or add additional context in comments.

Comments

0

Use a custom xml serializer

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.