Click here to Skip to main content
15,884,353 members
Articles / Programming Languages / XML
Tip/Trick

Differences in XML Serialization when [XmlElement] and [XmlText] are Combined

Rate me:
Please Sign up or sign in to vote.
4.78/5 (4 votes)
14 Feb 2015CPOL1 min read 28.7K   73   3   3
This tip shows the differences in XML serialization when a serializable class has a combination of [XmlElement] and [XmlText].

Introduction

This tip shows the differences in XML serialization when a serializable class has a combination of [XmlElement] and [XmlText].

Background

XML serialization can be done in various ways and techniques. In this tip, I would like to show a difference I experienced with a serializable class declaring a collection as [XmlElement] and a string as [XmlText].

Using the Code

Serializable Class

This class has the following properties:

  • A string as an attribute - [XmlAttribute]
  • A string as a text attribute - [XmlText]
  • A collection as an element - [XmlElement]
C#
[XmlType(AnonymousType = true)]
public class Person
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlText]
    public string Text { get; set; }

    [XmlElement("person")]
    public Collection<Person> Children { get; set; }

    public bool ShouldSerializeChildren()
    {
        return Children != null && Children.Count > 0;
    }

    public string Serialize()
    {
        var sw = new StringWriter();

        var serializer = new XmlSerializer(typeof(Person));
        var ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        serializer.Serialize(sw, this, ns);

        return sw.ToString();
    }
}

Serializing the Class Without Assigning a Text Property

Assigning only the name attribute and the collection element.

C#
var person = new Person
{
    Name = "name",
    Children =
        new Collection<Person>
        {
            new Person {Name = "child1", Text = "child1Text"},
            new Person {Name = "child2", Text = "child2Text"}
        }
};

var personWithoutText = person.Serialize();

Console.WriteLine("Person without text attribute has new lines:");
Console.WriteLine("-------------------------------------------");
Console.WriteLine(personWithoutText);
Console.WriteLine();

The Result

The result would be a nice indented XML with newlines between the collection items.

XML
<?xml version="1.0" encoding="utf-16"?>
<Person name="name">
  <person name="child1">child1Text</person>
  <person name="child2">child2Text</person>
</Person>

Serializing the Class After Assigning a Text Property

C#
person.Text = "text";

            var personWithTextAttribue = person.Serialize();
            Console.WriteLine("Person with text attribute has no new lines:");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine(personWithTextAttribue);

            Console.ReadLine();

The Result

The result would be an XML without newlines between the collection items.

XML
<?xml version="1.0" encoding="utf-16"?>
<Person name="name">text<person name="child1">child1Text</person>
<person name="child2">child2Text</person></Person>

Conclusion

The workaround I found for having newlines between collection items, was to make sure there is no text attribute in the serializable class.

Points of Interest

Why did I declare the collection property as XmlElement?

A collection that is not declared as XmlElement, its items are encoded as a sequence of elements, nested under an element named after the property. (See XmlElementAttribute in MSDN)

Something like this:

XML
<myserializableclass>
    <wrappingelement>
        <item>item1</item>
        <item>item2</item>
        <item>item3</item>
    <myserializableclass>
</myserializableclass>

In order to avoid the element wrapping the collection's items, I am declaring the collection as [XmlElement].
The serialization result would then be:

XML
<MySerializableClass>
    <item>item1</item>
    <item>item2</item>
    <item>item3</item>
 </MySerializableClass>

History

  • 14th February, 2015: Initial version
  • 17th February, 2015: Edited conclusion and updated code (fixed namespace and XML attributes)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Israel Israel
I am currently working in C# and angularJs.
I have a B.Sc. in Physics and Computer Science and I am a software engineer since 2006 in Israel.

Comments and Discussions

 
QuestionThank you Pin
Avi Farah2-Jun-17 8:20
Avi Farah2-Jun-17 8:20 
QuestionVery Nice, Thanks! You can also use XmlWriterSettings Pin
pablito99815-Feb-15 23:54
pablito99815-Feb-15 23:54 
AnswerRe: Very Nice, Thanks! You can also use XmlWriterSettings Pin
Ifat Chitin Morrison18-Feb-15 6:25
Ifat Chitin Morrison18-Feb-15 6:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.