|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Re: How do you prevent null elements from being serialized?1. De-serializing from > ....I get name=Joe, Age=37 and AgeSpecified = true (not false as you report).> <person> > <name>Joe</name> > <age>37</age> > </person> > Also, changing the Name from Joe to Bob should not affect Age or AgeSpecified, as you report. Also, changing Age does not directly affect AgeSpecified. These things are true, unless you have put some non-default handling in the property getter/setter. > What I would like to see happen is if ValueSpecified is false, then just This is the default behavior?, so I don't understand why you are asking > leave that element off altogether. Is there a way to do this? this. The code enclosed below demonstrates this, and some other interesting things in XML serialization. In fact you have to do something special in order to get an empty element (eg "<Age />") to appear in an XML stream output from the .NET XML Serializer. If you use isnullable:=True in the XmlElementAttribute, you will get <Age xsi:nil="true" />, which is not quite the same thing. -Dino ----- Begin Code ----- // XmlIgnoreTest.cs // // Exercises some of the XmlIgnore stuff // // compile with: // // (c) Ionic Shade // Wed, 17 Nov 2004 10:02 // using System.IO; using System.Xml.Serialization; // This is the default class generated from xsd.exe [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] public class Person { [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Name; [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] public System.Single Age; [System.Xml.Serialization.XmlIgnoreAttribute()] public bool AgeSpecified; } namespace Ionic { public class XmlTextWriterFormattedNoDeclaration : System.Xml.XmlTextWriter { public XmlTextWriterFormattedNoDeclaration (System.IO.TextWriter w) : base(w) { Formatting= System.Xml.Formatting.Indented;} public override void WriteStartDocument () { } } public class TestDriver { static void Main(string[] args) { try { string OriginalXml= "<Person>\n" + " <Name>Joe</Name>\n" + " <Age>37</Age>\n" + "</Person>\n" + ""; System.Console.WriteLine("\n============================================\nOriginal XML:\n"+ OriginalXml); XmlSerializer s1 = new XmlSerializer(typeof(Person)); Person p= null; using (System.IO.StringReader sr= new System.IO.StringReader(OriginalXml)) { p = (Person) s1.Deserialize(sr); } // suppress default namespace entries in the root elt XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add( "", "" ); // use a custom TextWriter to suppress the XML declaration System.Console.WriteLine("\n============================================\nOriginal values:"); s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); System.Console.WriteLine("\n============================================\nChanging the name does not change the age:"); p.Name= "Bob"; s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); System.Console.WriteLine("\n============================================\nUn-specifying the Age results in this:"); p.AgeSpecified= false; s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); string OriginalXml2= "<Person>\n" + " <Name>Shirley</Name>\n" + " <Age />\n" + "</Person>\n" + ""; System.Console.WriteLine("\n============================================\nCase 2: Original XML:\n"+ OriginalXml2); p=null; try { System.Console.WriteLine("\n(De-serializing from this will fail...)\n"); using (System.IO.StringReader sr= new System.IO.StringReader(OriginalXml2)) { p = (Person) s1.Deserialize(sr); } } catch (System.InvalidOperationException ex1) { System.Console.WriteLine("As Expected, an Exception was generated: " + ex1); } if (p!= null) { System.Console.WriteLine("\n============================================\nOriginal values:"); s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); } p= new Person(); p.Name= "Henry"; System.Console.WriteLine("\n============================================\nNew Instance, setting only Name:"); s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); p.Age= 66; System.Console.WriteLine("\n============================================\nalso setting Ageon that instance:"); s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); p.AgeSpecified= true; System.Console.WriteLine("\n============================================\nand now setting AgeSpecified:"); s1.Serialize(new XmlTextWriterFormattedNoDeclaration(System.Console.Out), p, ns); System.Console.WriteLine("\n"); } catch (System.Exception e1) { System.Console.WriteLine("Exception!\n" + e1); } } } } ----- End Code ----- Show quote "Kenny Mullican" <nospam-kenny!@nowayemonarch.net> wrote in message news:%23uvw%23J$xEHA.4040@TK2MSFTNGP11.phx.gbl... >I am using complex types in order to support serialization/deserialization >of floating point numbers, since floating points can't be null. > > > I've seen how to suppress attributes that are "not specified", such as > having a float member called Value, and a bool member called > ValueSpecified. This instructs the XML Serializer to omit that attribute > altogether if it wasn't "Specified". But how can I tell it to omit the > XML element altogether? > > > Here's the problem: > > > I deserialize an object that looks like this: > > > <person> > > <name>Joe</name> > > <age>37</age> > > </person> > > > > When deserialized, I get an object of type person, with a field age of > type floatType which has Value = 37 and ValueSpecified = false. > > > If I change name to "Bob" (p.name = "Bob"), and then immediately serialize > that object to XML, I get: > > > <person> > > <name>Bob</name> > > <age /> > > </person> > > > > This indicates that age should now be null (if I pass this off to a SOAP > server for instance), or if that value is not allowed to be nulled, then I > get a SOAP exception. > > > If I explicitly set p.age.ValueSpecified = true or set p.age.Value = 36 > (which implicitly sets ValueSpecified to true) > > > Then I get the expected > > > <person> > > <name>Bob</name> > > <age>36</age> > > </person> > > > > What I would like to see happen is if ValueSpecified is false, then just > leave that element off altogether. Is there a way to do this? > > > Thanks for your help > > Kenny > > |
|||||||||||||||||||||||