none
Xml Serialize Empty Elements

    Question

  • I am currently running int some issues with serialization. Basically, with empty or null elements, after serialization, it would produciton elements like

    <ElementA />

    Is it possible to enforce the way how it is serialized so that it would produce the following instead?

    <ElementA></ElementA>

     

    Currently, I am doing a hack, where after deserialization, I check each element for empty or null. If it is, I replace the value with some garbage data. So when it comes to serialization, I serialize the obj into a StringWriter, And then search for that garbage data and replace that with empty string.

    Finally, I write the string via TextWriter. That does the trick, but this is such a hack that there has to be a way to overcome this silly little constraint.

     

    I tried to set the XmlAttribute IsNullable = true in proxy code. But that doesn't make a darn difference.

     

    Any suggestions will be greatly appreciated!

    Wednesday, October 03, 2007 1:12 AM

Answers

  • The faster and safer way of doing this is by writing your own subclass of the XmlWriter and give it to XmlSerializer.

    YourXmlWriter would aggregate standard one and would translate all WriteEndElement() calls to WriteFullEndElement() calls. 

     

    Wednesday, October 03, 2007 7:06 AM

All replies

  • <ElementA /> and <ElementA></ElementA> are equivalent serial representations of the same Xml data. As a general guideline, any reliance on distinguishability of these two forms is not recommended.


    Could you explain why <ElementA /> is not OK for your application?

    Wednesday, October 03, 2007 3:38 AM
  • I understand that it is not recommended to differentiate between these two representations of empty or null elements, but  the server that I make request to requires it. I don't have control over that.

     

    Unfortunately, I can't elaborate anymore on the the type of service or what server it is. The key point is that I need to generate <ElementA></ElementA> If there is a way, please advise.

     

    Thank you!

    Wednesday, October 03, 2007 6:28 AM
  • There's a fine difference between and - The first is null the second is string.Empty (to say  it in .NET words). I don't think that the serializer allows you to change that.

     

    But you could go over the output XML and use a RegEx to replace all like:

     

    Code Block

    string xml = "<element /><element2/><element3></element3>";

     

    MatchCollection c = Regex.Matches(xml, "<.+?/>");

    foreach(Match m in c)

    {

      string name = m.Value.Substring(1, m.Value.Length - 3);

      xml = xml.Replace(m.Value, "<" + name + "></" + name + ">");

    }

     

    Wednesday, October 03, 2007 6:51 AM
  • The faster and safer way of doing this is by writing your own subclass of the XmlWriter and give it to XmlSerializer.

    YourXmlWriter would aggregate standard one and would translate all WriteEndElement() calls to WriteFullEndElement() calls. 

     

    Wednesday, October 03, 2007 7:06 AM
  •  

    Clearly your version would be safer but leaves a level of complexity that may cost more time than is worth for a simple need. I did use the regex version and made a call to my ToString override (which was an internal serialize anyway) and just called it ToLongString( ). It's only going to be used for development anyway.
    Wednesday, October 10, 2007 6:57 PM
  • Hi.

    I have another question.

    When i serialize an object with empty or null properties, it doesn't produce  any tag.

    For exemple i have an object applicant.

    If i dont set any value at applicant.surName, xml doesnt contain any surName tag.

    But i need <surName/>.

    How can i resolve this?

     

    Thanks

    Wednesday, April 16, 2008 9:37 AM
  • Use IsNullable as follows:

    Code Snippet

    [XmlElement(IsNullable=true)]

    public string Surname

     

     

    But note that the xsi: nil attribute will be applied as well so you get e.g.

    Code Snippet

    <Applicant xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Surname xsi:nil="true" />
    </Applicant>

     

     

    The xsi: nil="true" is the W3C XML schema instance way of saying that the element is null.

    Wednesday, April 16, 2008 12:00 PM
  • Is there a way to remove the xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" and xsi:nil="true" from the serialization result?

    Thanks
    Friday, April 24, 2009 11:41 AM
  • Is there a way to remove the xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xmlns:xsd="http://www.w3.org/2001/XMLSchema" and xsi:nil="true" from the serialization result?

    Thanks

    You can try to strip the result of them:

                XmlSerializer ser = new XmlSerializer(typeof(Foo));
                Foo foo1 = new Foo() { Bar = "foobar" };
    
    
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "http://www.w3.org/2001/XMLSchema-instance");
                ns.Add("", "http://www.w3.org/2001/XMLSchema");
                ser.Serialize(Console.Out, foo1, ns);
    I have however not tried what happens when one of those two namespaces is actually needed in the serialized result e.g. with xsi : type attributes.


    MVP XML My blog
    Friday, April 24, 2009 12:22 PM