Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Your problem occurs because of during deserialization XmlSerializer first create an object by calling default constructor and then call <strong>ReadXml</strong> method to set property values so <strong>ReadXml</strong> can't cancel object creation. Is it necessary to serialize null values to see it in xml? I mean that you may avoid this by using non-List collection. For example create your custom collection:</p> <pre><code>public class MyCollection : System.Collections.ObjectModel.Collection&lt;MyFrac&gt; { protected override void InsertItem(int index, MyFrac item) { if(item == null) return; base.InsertItem(index, item); } protected override void SetItem(int index, MyFrac item) { if(item == null) { base.RemoveAt(index); } else { base.SetItem(index, item); } } } </code></pre> <p>Use it in your <strong>MyData</strong> class:</p> <pre><code>public class MyData { [XmlArrayItem("Frac")] public MyCollection Fractions; } </code></pre> <p>And then serialization/deserialization works as you want:</p> <pre><code> public static void Main(string[] args) { var data = new MyData(); data.Fractions = new MyCollection(); data.Fractions.Add(new MyFrac { N = "1", D = "2" }); data.Fractions.Add(null); data.Fractions.Add(null); data.Fractions.Add(new MyFrac { N = "3", D = "6" }); var serializer = new XmlSerializer(typeof(MyData)); StringBuilder sb = new StringBuilder(); using (var writer = new StringWriter(sb)) { serializer.Serialize(writer, data); } // Dump XML Console.WriteLine(sb.ToString()); using (var reader = new StringReader(sb.ToString())) { var data2 = (MyData)serializer.Deserialize(reader); foreach (var element in data2.Fractions) { Console.WriteLine(element); } } Console.ReadLine(); } </code></pre> <p>Serialized xml:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-16"?&gt; &lt;MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt; &lt;Fractions&gt; &lt;Frac&gt;1/2&lt;/Frac&gt; &lt;Frac&gt;3/6&lt;/Frac&gt; &lt;/Fractions&gt; &lt;/MyData&gt; </code></pre> <p>Outputs:</p> <p><strong>1/2</strong></p> <p><strong>3/6</strong></p> <p><strong>Update</strong></p> <p>Ok, you need a colletion with custom serialization rules. Let's implement it:</p> <pre><code>public class MyCollection&lt;T&gt; : Collection&lt;T&gt;, IXmlSerializable where T: class { public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { var serializer = new XmlSerializer(typeof(T)); var wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) return; while (reader.NodeType != XmlNodeType.EndElement) { if (reader.IsEmptyElement) { reader.Read(); Items.Add(null); continue; } var item = (T)serializer.Deserialize(reader); Items.Add(item); } reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { var serializer = new XmlSerializer(typeof (T)); foreach (var myFrac in Items) { serializer.Serialize(writer, myFrac); } } } </code></pre> <p>Usage:</p> <pre><code>public class MyData { public MyCollection&lt;MyFrac&gt; Fractions; } class Program { static void Main(string[] args) { var data = new MyData(); data.Fractions = new MyCollection&lt;MyFrac&gt;(); data.Fractions.Add(new MyFrac { N = "1", D = "2" }); data.Fractions.Add(null); data.Fractions.Add(null); data.Fractions.Add(new MyFrac { N = "3", D = "6" }); var serializer = new XmlSerializer(typeof(MyData)); StringBuilder sb = new StringBuilder(); using (var writer = new StringWriter(sb)) { serializer.Serialize(writer, data); } // Dump XML Console.WriteLine(sb.ToString()); Trace.WriteLine(sb.ToString()); using (var reader = new StringReader(sb.ToString())) { var data2 = (MyData)serializer.Deserialize(reader); foreach (var fraction in data2.Fractions) { var output = fraction == null ? "null" : fraction.ToString(); Console.WriteLine(output); Trace.WriteLine(output); } } Console.ReadLine(); } } </code></pre> <p>Output xml:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-16"?&gt; &lt;MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt; &lt;Fractions&gt; &lt;MyFrac&gt;1/2&lt;/MyFrac&gt; &lt;MyFrac xsi:nil="true" /&gt; &lt;MyFrac xsi:nil="true" /&gt; &lt;MyFrac&gt;3/6&lt;/MyFrac&gt; &lt;/Fractions&gt; &lt;/MyData&gt; </code></pre> <p>Output data:</p> <p><strong>1/2</strong></p> <p><strong>null</strong></p> <p><strong>null</strong></p> <p><strong>3/6</strong></p> <p>I think this is what you want.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload