0

I have the following XML structure:

<TabHierarchy>
    <Tab Name="Tab1"/>
    <TabGroup Name="Group1">                
        <Tab Name="Tab2"/>
        <Tab Name="Tab3"/>
        <Tab Name="Tab4"/>
    </TabGroup>
    <Tab Name="Tab5"/>
    <TabGroup Name="Group2">
        <Tab Name="Tab6"/>
        <TabGroup Name="Group3">
            <Tab Name="Tab7"/>
            <Tab Name="Tab8"/>
        </TabGroup>
        <Tab Name="Tab9"/>
    </TabGroup>
    <Tab Name="Tab10"/>
</TabHierarchy>

My C# classes:

public class XmlTabHierarchy
{
    public XmlTabHierarchy()
    {
        Tab = new List<XmlTab>();
        TabGroup = new List<XmlTabGroup>();
        TabReport = new List<XmlReportTab>();
    }
    [XmlElement("Tab")] public List<XmlTab> Tab { get; set; }
    [XmlElement("TabGroup")] public List<XmlTabGroup> TabGroup { get; set; }
    [XmlElement("ReportTabs")] public List<XmlReportTab> TabReport { get; set; }
}
public class XmlTab
{
    [XmlIgnore] public int Order { get; set; }
    [XmlIgnore] public string Group { get; set; }
    [XmlIgnore] public bool Use { get; set; }
    [XmlIgnore] public bool ByUser { get; set; }
    [XmlIgnore] public bool KeyTab { get; set; }
    [XmlIgnore] public string Tab { get; set; }
    [XmlAttribute("Name")] public string TabClean { get; set; }
    [XmlAttribute("Alias")] public string Alias { get; set; }
    [XmlIgnore] public string Type { get; set; }
    [XmlIgnore] public bool Duplicate { get; set; }
}
public class XmlTabGroup
{
    public XmlTabGroup()
    {
        Tab = new List<XmlTab>();
        TabGroup = new List<XmlTabGroup>();
    }
    [XmlIgnore] public int Order { get; set; }
    [XmlIgnore] public int GroupId { get; set; }
    [XmlAttribute("Name")] public string Group { get; set; }
    [XmlAttribute("Alias")] public string Alias { get; set; }
    [XmlElement("Tab")] public List<XmlTab> Tab { get; set; }
    [XmlElement("TabGroup")] public List<XmlTabGroup> TabGroup { get; set; }
}

The issue I am having is, being able to sort them correctly. As seen in the example XML, Tabs can be between TabGroups. The ReportTabs are always at the end. There is one post here with a similar problem but I don't know how to implement it for my project. Keep sort when deserialize and serialize XML using XmlSerializer

Fabian228
  • 23
  • 5
  • The link is not the same issue you are having. You have a tree structure while the link is a fixed structure. You need a recursive algorithm to do the sorting. See : https://en.wikipedia.org/wiki/Tree_sort?force_isolation=true#:~:text=A%20tree%20sort%20is%20a,is%20available%20in%20sorted%20order. – jdweng Sep 02 '22 at 08:55
  • I didn't say it is the same. Getting the correct order isn't the issue, the serialization itself is the problem. – Fabian228 Sep 02 '22 at 10:27
  • Serialization reads the xml in the order that is in file and writes to the classes in same order. There is no sorting. You said "The issue I am having is, being able to sort them correctly" – jdweng Sep 02 '22 at 12:01
  • Yes but the thing I don't know is how to structure my classes to be able to achieve it. The way the classes are now, I can only do Tabs first, TabGroups second. – Fabian228 Sep 02 '22 at 12:22
  • Look at the WIKI article. You do not understand a tree sort. The classes structures do not have to be changed. – jdweng Sep 02 '22 at 17:17
  • It is not possible to serialize the way I need it with my current structure as far as I am aware, this has nothing to do with trees. The reason being, I have 2 different lists which need be mixed. – Fabian228 Sep 05 '22 at 07:33

1 Answers1

0

XML specification the order of elements are not required. The code below creates the XML according to the XML specification.

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

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

            XmlTabHierarchy hierarchy = new XmlTabHierarchy()
            {
                Tab = new List<XmlTab>()
                {
                    new XmlTab() { TabClean = "Tab1"},
                    new XmlTab() { TabClean = "Tab5"},
                    new XmlTab() { TabClean = "Tab10"}
                },
                TabGroup = new List<XmlTabGroup>()
                {
                    new XmlTabGroup()
                    {
                        Group = "Group1",
                        Tab = new List<XmlTab>()
                        {
                            new XmlTab() { TabClean = "Tab2"},
                            new XmlTab() { TabClean = "Tab3"},
                            new XmlTab() { TabClean = "Tab4"}
                        }
                    },
                    new XmlTabGroup()
                    {
                        Group = "Group2",
                        Tab = new List<XmlTab>()
                        {
                            new XmlTab() { TabClean = "6" },
                            new XmlTab() { TabClean = "9"},
                        },
                        TabGroup = new List<XmlTabGroup>()
                        {
                            new XmlTabGroup()
                            {
                                Group = "Group3",
                                Tab = new List<XmlTab>()
                                {
                                    new XmlTab() { TabClean = "Tab7"},
                                    new XmlTab() { TabClean = "Tab8"}
                                }
                            }
                        }
                    }
                }
                
            };

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(FILENAME, settings);
            XmlSerializer serializer = new XmlSerializer(typeof(XmlTabHierarchy));
            serializer.Serialize(writer, hierarchy);
            
        }

    }
    public class XmlTabHierarchy
    {
        public XmlTabHierarchy()
        {
            Tab = new List<XmlTab>();
            TabGroup = new List<XmlTabGroup>();
        }
        [XmlElement("Tab")] 
        public List<XmlTab> Tab { get; set; }
        [XmlElement("TabGroup")] 
        public List<XmlTabGroup> TabGroup { get; set; }
    }
    public class XmlTab
    {
        [XmlAttribute("Name")] 
        public string TabClean { get; set; }
        [XmlAttribute("Alias")] 
        public string Alias { get; set; }
    }
    public class XmlTabGroup
    {
        public XmlTabGroup()
        {
            Tab = new List<XmlTab>();
            TabGroup = new List<XmlTabGroup>();
        }
        [XmlAttribute("Name")] 
        public string Group { get; set; }
        [XmlAttribute("Alias")] 
        public string Alias { get; set; }
        [XmlElement("Tab")] 
        public List<XmlTab> Tab { get; set; }
        [XmlElement("TabGroup")] 
        public List<XmlTabGroup> TabGroup { get; set; }
    }


}
 
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • The order does matter for the application which is reading the file. I managed to do it now. It was basically like in the other link. I made a base class, let my other two classes inherit from it and only serialize the base class with two XmlElement definitions. – Fabian228 Sep 06 '22 at 11:27