Home > Software engineering >  C# XML Serialization having elements side-by-side
C# XML Serialization having elements side-by-side

Time:12-21

I am currently trying to understand the concept of serializing objects to XML with C#. I already got to a point where everything is working fine, but now I got the task to format the XML Output file in such a way, where the elements are side-by-side instead of underneath each other. For example:

This is how it needs to look like

<House>
  <Address>
    <Street>Some Street</Street><HouseNo>123</HouseNo><State>Texas</State>
  </Address>
<House>

But I only manage to get it to look like this:

<House>
  <Address>
    <Street>Some Street</Street>
    <HouseNo>123</HouseNo>
    <State>Texas</State>
  </Address>
</House>

Is there any way to format the output the way I described in the first example? Any help would be much appreciated.

I already tried to change some XmlWriterSettings, like Indent or NewLineHandling but none have worked so far. I also tried to read the XmlSerializer Code to try and understand what is happening or where to make changes to get to the result I want but that didn't seem to go all well.

CodePudding user response:

You could crate an address class with custom serialization, here is a full working example,

using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.Serialization;
                    
public class Program
{
    public static void Main()
    {
        var houseBefore = new House
        {
            Address = new FlatAddress
                              {
                                 Street = "SomeStreet",
                                 HouseNo = "123",
                                 State = "Texas"
                              }
        };
        
        var serializer = new XmlSerializer(typeof(House));
        string xml;
        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, houseBefore);
            xml = writer.ToString();
        }
        
        Console.WriteLine(xml);
        
        House houseAfter;
        using (var reader = new StringReader(xml))
        {
            houseAfter = serializer.Deserialize(reader) as House;
        }
        
        Debug.Assert(houseBefore.Address.Street == houseAfter.Address.Street);
        Debug.Assert(houseBefore.Address.HouseNo == houseAfter.Address.HouseNo);
        Debug.Assert(houseBefore.Address.State == houseAfter.Address.State);
    }
}

public sealed class House
{
    public FlatAddress Address { get; set; }
}

public sealed class FlatAddress : IXmlSerializable
{
    public string Street { set; get; }
    public string HouseNo { set; get; }
    public string State { set; get; }
    
    public XmlSchema GetSchema()
    {
        return default;
    }
    
    public void ReadXml(XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    case nameof(Street):
                        this.Street = reader.ReadElementContentAsString();
                        break;

                    case nameof(HouseNo):
                        this.HouseNo = reader.ReadElementContentAsString();
                        break;

                    case nameof(State):
                        this.State = reader.ReadElementContentAsString();
                        break;
                }
            }
        }
    }
    
    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString(nameof(Street), this.Street);
        var houseNoXml = new XElement(nameof(HouseNo), this.HouseNo);
        writer.WriteRaw(houseNoXml.ToString());
        var stateXml = new XElement(nameof(State), this.State);
        writer.WriteRaw(stateXml.ToString());
        
        if (writer.Settings.NewLineHandling == NewLineHandling.Replace)
        {
            writer.WriteRaw(writer.Settings.NewLineChars);
        }
        
        if (writer.Settings.Indent)
        {
            writer.WriteRaw(writer.Settings.IndentChars);
        }
    }
}
  • Related