1

I have the following classes in a serialization:

[XmlRoot()]
public class XmlExample
{
private NodeA_Elem _nodea;
[XmlElemnt("NodeA")]
public NodeA_Elem NodeA
{
    get
    {
        return _nodea;
    }
    set
    {
        _nodea=value;
    }
}

private NodeB_Elem _nodeb;
[XmlElemnt("NodeB")]
public NodeB_Elem NodeB
{
    get
    {
        return _nodeb;
    }
    set
    {
        _nodeb=value;
    }
}

private NodeC_Elem _nodec;
[XmlElemnt("NodeC")]
public NodeC_Elem NodeC
{
    get
    {
        return _nodec;
    }
    set
    {
        _nodec=value;
    }
}
public class NodeA_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeB_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeC_Elem
{
    [XmlText()]
    public string value{get;set;}
}

If the value property of any classes NodaA, NodeB or NodeC is null or empty I have the following result:

<XmlExample>
   <NodeA/>
   <NodeB/>
   <NodeC/>
</XmlExample>

What I have to do to these nodes don't appear like empty nodes if I don't set the value property?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • See this answer - http://stackoverflow.com/questions/5818513/xml-serialization-hide-null-values – Denis Jan 05 '15 at 17:06
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Jan 05 '15 at 17:11

3 Answers3

2

You can use ShouldSerialize* pattern, something like this:-

public bool ShouldSerializeNodeA() {
    return NodeA != null;
}

Refer here :- Conditional xml serialization

Update:

Make it non nullable:-

[XmlElement(IsNullable = false)]

Edit:

Earlier I mentioned :-

public bool ShouldSerializeNodeA() {
    return NodeB != null;
}

My mistake, it should be like this:-

public bool ShouldSerializeNodeA() {
    return NodeA != null;
}
Community
  • 1
  • 1
King
  • 183
  • 10
  • NodeB property returns ``NodeB_Elem`` class, not ``string``. – Denis Jan 05 '15 at 17:14
  • the type string must be non-nullable. The ShouldSerialize pattern is not working – João Paulo Jan 05 '15 at 17:29
  • I'm using IsNullable=false, but it didn't work. The class NodeB_Elem is instantiated in xmlExample constructor, but when I don't set value property it returns a empty nodeB. – João Paulo Jan 05 '15 at 17:40
  • i had mistakenly used NodeB != null condition for ShouldSerializeNodeA. Have you used it properly ? Please have a go through again, does that help ? I have edited in the answer. Also please provide you constructor code. – King Jan 05 '15 at 17:52
  • King, the constructor of the xmlexample class just instantiate the classes NodeA, B and C. Please, wait for a while, soon as possible I will edit my answer and provide the code. I'm answering you at my cellphone. – João Paulo Jan 05 '15 at 20:42
1

You can also use a boolean property with the suffix xSpecified to indicate whether or not to serialize a property. This is used by Xml clients which consume xml which have a default value (e.g. as specified with default=xxx in an XSD):

public bool NodeASpecified
{
    get { return _nodea != null && !String.IsNullOrEmpty(_nodea.value); }
}

Do not mark these Specified properties with any Xml attributes.

Not related, but hard coding the *Specified properties to true in a partial class is useful if you have consumed a web service which has a default and a minOccurs=0, which would otherwise not be sent at all to the service if the value was coincidentally the same as the default value.

StuartLC
  • 104,537
  • 17
  • 209
  • 285
0

I added up some comments and find a solution. I could use the ShouldSerialize pattern in my code. The resulting code is:

[XmlRoot()]
public class XmlExample
{
    private NodeA_Elem _nodea;
    [XmlElemnt("NodeA")]
    public NodeA_Elem NodeA
    {
        get
        {
            return _nodea;
        }
        set
        {
            _nodea=value;
        }
    }
    public bool ShouldSerializeNodeA()
    {
        return !String.IsNullOrEmpty(_nodea.value);
    }

    private NodeB_Elem _nodeb;
    [XmlElemnt("NodeB")]
    public NodeB_Elem NodeB
    {
        get
        {
            return _nodeb;
        }
        set
        {
            _nodeb=value;
        }
    }
    public bool ShouldSerializeNodeB()
    {
        return !String.IsNullOrEmpty(_nodeb.value);
    }
    private NodeC_Elem _nodec;
    [XmlElemnt("NodeC")]
    public NodeC_Elem NodeC
    {
        get
        {
            return _nodec;
        }
        set
        {
            _nodec=value;
        }
    }
    public bool ShouldSerializeNodeC()
    {
        return !String.IsNullOrEmpty(_nodec.value);
    }
}

public class NodeA_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeB_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeC_Elem
{
    [XmlText()]
    public string value{get;set;}
}

Edit:

Here is the full code of my example:

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

namespace Serialization_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            MyXmlDocument document = new MyXmlDocument();
            document.MyExample.NodeA.value = "Value To Node A";
            document.MyExample.NodeC.value = "Value To Node C";
            document.WriteToXml(@"C:\Users\user_Name\Desktop\mydocument.xml");
        }
    }

    [XmlRoot("xmlExample")]
    public class XmlExample
    {
        private NodeA_Elem _nodea;
        [XmlElement()]
        public NodeA_Elem NodeA
        {
            get
            {
                return _nodea;
            }
            set
            {
                _nodea = value;
            }
        }
        public bool ShouldSerializeNodeA()
        {
            return !String.IsNullOrEmpty(_nodea.value);
        }

        private NodeB_Elem _nodeb;
        [XmlElement("NodeB")]
        public NodeB_Elem NodeB
        {
            get
            {
                return _nodeb;
            }
            set
            {
                _nodeb = value;
            }
        }
        public bool ShouldSerializeNodeB()
        {
            return !String.IsNullOrEmpty(_nodeb.value);
        }
        private NodeC_Elem _nodec;
        [XmlElement("NodeC")]
        public NodeC_Elem NodeC
        {
            get
            {
                return _nodec;
            }
            set
            {
                _nodec = value;
            }
        }
        public bool ShouldSerializeNodeC()
        {
            return !String.IsNullOrEmpty(_nodec.value);
        }

        public XmlExample()
        {
            _nodea = new NodeA_Elem();
            _nodeb = new NodeB_Elem();
            _nodec = new NodeC_Elem();
        }
    }

    public class NodeA_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class NodeB_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class NodeC_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class MyXmlDocument
    {
        private XmlExample _myexample;
        public XmlExample MyExample
        {
            get
            {
                return _myexample;
            }
            set
            {
                _myexample = value;
            }
        }

        public void WriteToXml(string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(XmlExample));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.Unicode;

            StringWriter txtwriter = new StringWriter();
            XmlWriter xmlwtr = XmlWriter.Create(txtwriter, settings);
            serializer.Serialize(xmlwtr, MyExample);

            StreamWriter writer = new StreamWriter(path);
            writer.Write(txtwriter.ToString());

            writer.Close();
        }

        public MyXmlDocument()
        {
            _myexample = new XmlExample();
        }
    }
}

If you compile it, you'll see that if I don't set the value for NodeB.value, it won't generate a empty node like was happening before.