F.P
F.P

Reputation: 17831

"Recursive" (?) omitting of empty values in XML Serialization

I have a target XML structure like this:

<object>
  <children>
    <object>
      <property name="Marketingfoto">
        <value>148-41_149-41.tif</value>
      </property>
      <property name="Produkttyp">
        <value/>
      </property>
      <property name="Produktname">
        <value language="en">Sealing</value>
        <value language="de">Dichtung</value>
      </property>
      <property name="ProduktnameMehrzahl">
        <value language="en"/>
        <value language="de">Dichtungen</value>
      </property>

As you can see, there are value elements without text. I want the XML Serializer to omit those, as they are taking up huge amounts of space in the resulting file.

Also, If a property element doesn't have any values with text in them, the whole property element should also be omitted.

So, it should basically "recursively" omit the elements if there is nothing to write, so that the resulting example looks like:

<object>
  <children>
    <object>
      <property name="Marketingfoto">
        <value>148-41_149-41.tif</value>
      </property>
      <property name="Produktname">
        <value language="en">Sealing</value>
        <value language="de">Dichtung</value>
      </property>
      <property name="ProduktnameMehrzahl">
        <value language="de">Dichtungen</value>
      </property>

How can I go about this? I tried using the ShouldSerialize method, but it doesn't seem to work on this particular serialization attribute combination.

The classes are:

[XmlRoot("object")]
public class XmlObject
{
    [XmlArray("children")]
    [XmlArrayItem("object")]
    public List<XmlObject> Children { get; set; }

public class XmlProperty
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("value")]
    public List<XmlPropertyValue> Values { get; set; }

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

public class XmlPropertyValue
{
    [XmlAttribute("language")]
    public string Language { get; set; }

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

    public bool ShouldSerializeValue()
    {
        return Value != null && !Value.Equals(String.Empty);
    }
}

Upvotes: 0

Views: 79

Answers (1)

Moti Azu
Moti Azu

Reputation: 5442

I tried to use ShouldSerialize in various ways and the best I could get to was <value />, couldn't make him not serialize an array item basically.

But using a custom property to filter out what you don't want would work.

[XmlIgnore]
public List<XmlPropertyValue> Values { get; set; }

[XmlElement("value")]
public List<XmlPropertyValue> ValuesForSerialization
{
    get
    {
        var bla = Values.Where(o => o.ShouldSerializeValue()).ToList();
        return bla;
    }
    set { Values = value; }
}

Tested, it works. It's not a neat solution and neither is anything that adds public members to your class (just like ShouldSerializeValue).

According to some sources you could make ValuesForSerialization internal if you use DataContractSerializer instead of XmlSerializer.

Upvotes: 1

Related Questions