Sss
Sss

Reputation: 1529

How to do serialisation of this nested xml

I am under a situation where i tried to do serialization :

My classes are like this:

 [XmlRoot(ElementName = "ps")]
  public class Ps
  {
   [XmlElement("sep")]
   public List<Sep> Sep { get { return a1; } }
   private readonly List<Sep> a1 = new List<Sep>(); 

   [XmlElement("pr")]
   public List<Pr> Pr { get { return b1; } }
   private readonly List<Pr> b1 = new List<Pr>();
 }


 [XmlRoot(ElementName = "attr")]
public class Attr
{     
    [XmlElement("type")],
    public string Type { get; set; }

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

}

    [XmlRoot(ElementName = "pr")]
          public class Pr
        {
            [XmlElement("name")]
            public string Name { get; set; }

            [XmlElement("comp")]
            public List<Comp> Comp { get { return b3; } }
            private readonly List<Comp> b3 = new List<Comp>();

        }
 [XmlRoot(ElementName = "sep")]
    public class Sep
    {
        [XmlElement("sep")]
        public string Sep { get; set; }

    }

 public void Main()
{

            Ps pc = new Ps()
              {
                Pr = { new Pr { Name = "Name1",  Component = { new Comp { Type = "CB", Attr = { new Attr { Value = "0" } } } } }, { new Pr { Name = "Name2" ,Comp = { new Comp { Type = "RB", Attr = { new Attr { Value = "l" ....And so On} } } } } } }
             ,
                Sep = { new Sep { Sep = "sep1" ..and so on} }  

              };
            var xml = pc.ToXml(); 
}

The xml obtained is supposed to be like this :

<ps>
    <pr>
        <name>name1</name>
        <comp>
            <type>CB</type>
            <attr>
                <value>0</value>
            </attr>
        </comp>
    </pr>
    <sep>sep1</sep>
    <pr>
        <name>name2</name>
        <comp>
            <type>RB</type>
            <attr>
                <value>1</value>
            </attr>
        </comp>
    </pr>
    <sep>sep2</sep>
    <pr>
        <name>name3</name>
        <comp>
            <type>CoM</type>
            <attr>
                <value>2</value>
            </attr>
        </comp>
    </pr>
    <sep>sep3</sep>
</ps>

But unfortunately it is like this:

<ps>
  <sep>sep1</sep>
  <sep>sep2</sep>
  <sep>sep3</sep>
  <pr>
      <name>name1</name>
       <comp>
            <type>CB</type>
            <attr>
                <value>0</value>
            </attr>
       </comp>
    </pr>    
    <pr>
        <name>name2</name>
        <comp>
            <type>RB</type>
            <attr>
                <value>1</value>
            </attr>
        </comp>
    </pr>    
    <pr>
        <name>name3</name>
        <comp>
            <type>CoM</type>
            <attr>
                <value>2</value>
            </attr>
        </comp>
    </pr>  
</ps>

The xml contains all "sep" together and all "pr" together. How to maintain the sequence of "pr" and "sep" as it is supposed to be obtained ? I tried using XElemnt but the problem is we do everythign statically there,Like this:

var el =   new XElement("ps",
                       new XElement("pr",
                           new XElement("name", "name1"),
                           new XElement("comp",
                               new XElement("type", "CB"),
                               new XElement("attr",
                                   new XElement("value", 0)
                               )
                           )
                       ),//And so on..

I also tried something like this :

 Ps pc = new Ps()
              {
                Pr = { new Pr { Name = "Name1",  Comp = { new Comp { Type = "Type1", Attr = { new Attr { Type = "Com" } } } } }, { new Pr { Name = "Name2" ,Comp = { new Comp { Type = "Type2", Attr = { new Attr { Type = "Sl" ....And so On} } } } } } }
             ,
                Sep = { new Sep { Sep = "sep1" ..and so on} }  
              , Pr = { new Pr { Name = "Name1",  Component //so on 
              ,Sep = { new Sep { Sep = "sep1" ..and so on} }  
              };
        var xml = pc.ToXml(); 

which will ofcourse not work duplicate intialisation of Pr ans sep.

We assign here like this XElement("name", "name1") but i want something like this ps Object1 = new ps(); and Object1.pr[0].Name= "name1"; How to achieve this ?

EDIT: I tried te code" below after Austinh's comments:

public void Main()
{
   List<object> lst = new List<object>();
   Ps pc = new Ps()
   {
          Pr = { new Pr { Name = "Name1",Comp = { new Comp { Type = "Type1", Attr = { new Attr { Type = "Combo"} } } } }}
     ,
          Sep = { new Sep{ Sep = "AutoSkew1" } }
    };

   Ps pc1 = new Ps()
   {
       Pr = { new Pr { Name = "Name3", Comp = { new Comp { Type = "Type3", Attr = { new Attr { Type = "Rb"} } } } } }
   ,
       Sep = { new Sep { Sep = "AutoSkew2" }}
   };
   lst.Add(pc);
   lst.Add(pc1);
   var xml = lst.ToXml();
}

But i have invalid excceptionhandled by user :There was an error generating the XML document.In the line serializer.Serialize(writer, objectToSerialize); in the code below:

public static string ToXml(this object objectToSerialize)
        {
            var writer = new StringWriter();
            var serializer = new XmlSerializer((objectToSerialize.GetType()));
            serializer.Serialize(writer, objectToSerialize);
            string xml = writer.ToString();
            return xml;
        }

Upvotes: 0

Views: 54

Answers (1)

Austinh100
Austinh100

Reputation: 598

I have not tested this so it may not work but here is a possible way to have a structure like that.

Adapted from: c# serialize nested class

public class Ps
{
    [XmlArray("ps")]
    public List<object> items { get { return a1; } }
    private readonly List<object> a1 = new List<object>(); 
}

And then add (sep or pr) to the Ps list when needed which will keep the order that it was added to.

Expanding on your main edit (implying implementation of above code):

public void Main()
{
   Ps pc = new Ps();
   pc.items.Add(new Pr { Name = "Name1",Comp = { new Comp { Type = "Type1", Attr = { new Attr { Type = "Combo"} } } } });
   pc.items.Add(new Sep{ Sep = "AutoSkew1" });

   pc.items.Add(new Pr { Name = "Name3", Comp = { new Comp { Type = "Type3", Attr = { new Attr { Type = "Rb"} } } } });
   pc.items.Add(new Sep { Sep = "AutoSkew2" });
   var xml = pc.items.ToXml();
}

Upvotes: 1

Related Questions