XML deserialisation - backwards compatability

Hello,

I have an issue where I've replaced a single class field with a number
of separate fields that allow more fine control.  The problem is that
my old files, saved using XmlSerialization, still have this old field
name in them, and I need to be able to read it and set the new fields
appropriately.

E.g. the if the old class

class MyClass
{
  public int area;
}

and the new version is now

class MyClass
{
  public int width;
  public int height;
}

then when executing:

XmlTextReader xmlReader = new XmlTextReader(filename);
XmlSerializer xs = new XmlSerializer(typeof(MyClass));
MyClass obj = (MyClass)xs.Deserialize(xmlReader);

I need to be able to look for the "area" value in old files, and set
width and height appropriately (e.g. to the square root of the area
value).

Is there a straightforward way of doing this?

Note the class has at least 30 other members, and that I'm using a
generic piece of code to do the actual serialization that's not
specific to MyClass, though of course I can put a test in to deal with
MyClass as a special case if necessary.
0
wizofaus (8)
4/11/2008 5:33:05 AM
dotnet.xml 7266 articles. 0 followers. Follow

3 Replies
986 Views

Similar Articles

[PageSpeed] 21

Maybe not straightforward, but: if you add a hidden Area property, and
tell it never to serialize, it should work.
Note I've used C# 3 auto-implemented properties for Width/Height -
just replace with standard properties if you are using C# 2; but don't
use public fields... pretty much "ever".

Marc

using System;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;

[Serializable]
public sealed class MyClass
{
    public int Width { get; set; }
    public int Height { get; set; }

    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
    public int Area
    {
        get { return Width * Height; }
        set { Width = Height = (int)Math.Sqrt(value); }
    }
    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
    public bool ShouldSerializeArea() { return false; }

    public override string ToString()
    {
        return string.Format("{0}x{1}", Width, Height);
    }
}

static class Program
{
    static void Main(string[] args)
    {
        XmlSerializer xs = new XmlSerializer(typeof(MyClass));
        MyClass item = new MyClass { Width = 3, Height = 5 };

        StringWriter writer = new StringWriter();
        xs.Serialize(writer, item);
        string xml = writer.ToString();

        Console.WriteLine(xml);

        using (StringReader sr = new StringReader(@"<MyClass><Area>25</
Area></MyClass>"))
        {
            MyClass oldStyle = (MyClass)xs.Deserialize(sr);
            Console.WriteLine(oldStyle);
        }
        using (StringReader sr = new StringReader(@"<MyClass><Width>7</
Width><Height>3</Height></MyClass>"))
        {
            MyClass newStyle = (MyClass)xs.Deserialize(sr);
            Console.WriteLine(newStyle);
        }
    }
}
0
4/11/2008 6:53:57 AM
On Apr 11, 4:53=A0pm, Marc Gravell <marc.grav...@gmail.com> wrote:
> Maybe not straightforward, but: if you add a hidden Area property, and
> tell it never to serialize, it should work.
> Note I've used C# 3 auto-implemented properties for Width/Height -
> just replace with standard properties if you are using C# 2; but don't
> use public fields... pretty much "ever".
>
> Marc
>
Thanks...I didn't know about the ShouldSerialize...() trick - that
solved the problem of the deprecated field being written to new files.
But ideally I don't want the deprecated field to be public either.
Not a biggie, though.
As for public fields - in this case the class is just a holder for
fairly raw data, where no particular validation is needed.
And the beauty of C# is you can change public fields to properties at
any point and existing code will continue to compile.
0
wizofaus (8)
4/11/2008 7:51:00 AM
> But ideally I don't want the deprecated field to be public either.

Well, it is pretty well hidden by the two attributes - but ultimately
XmlSerializer works on public properties. If you have .NET 3.0,
another option is DataContractSerializer (shown below), since this can
serialize private members; and a third option is custom serialization
(IXmlSerializable), but this is considerably more work.

> As for public fields - in this case the class is just a holder for
> fairly raw data, where no particular validation is needed.

Then in VS2008 / C# 3, auto implemented properties are definitely the
way to go.

> And the beauty of C# is you can change public fields to properties at
> any point and existing code will continue to compile.

That isn't entirely true... first: it forces you to rebuild everything
that references it, and second: there are cases when this simply isn't
true; two obvious examples come to mind (there are others):

* using the field as a "ref" or "out" parameter to a method [can't use
properties as "ref" or "out"]
* if the field represents a mutable struct [which you shouldn't have
anyway], and you are changing nested properties [change gets discarded
with a property]

It will almost certainly break binary serialization, too.

Marc

## DataContract example ##

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

[DataContract(Namespace="")]
public sealed class MyClass
{
    [DataMember(IsRequired = false)]
    public int Width { get; set; }
    [DataMember(IsRequired=false)]
    public int Height { get; set; }

    [DataMember(Name="Area", IsRequired=false,
EmitDefaultValue=false)]
    private int? AreaFacade
    {
        get { return null; }
        set {
            if (value.HasValue)
            {
                Width = Height = (int)Math.Sqrt(value.Value);
            }
        }
    }

    public override string ToString()
    {
        return string.Format("{0}x{1}", Width, Height);
    }
}

static class Program
{
    static void Main(string[] args)
    {
        DataContractSerializer xs = new
DataContractSerializer(typeof(MyClass));
        MyClass item = new MyClass { Width = 3, Height = 5 };

        StringWriter writer = new StringWriter();
        using (XmlWriter xw = XmlWriter.Create(writer))
        {
            xs.WriteObject(xw, item);
            xw.Close();
        }
        string xml = writer.ToString();

        Console.WriteLine(xml);

        using (XmlReader xr = XmlReader.Create(new
StringReader(@"<MyClass><Area>25</Area></MyClass>")))
        {
            MyClass oldStyle = (MyClass)xs.ReadObject(xr);
            Console.WriteLine(oldStyle);
        }
        using (XmlReader xr = XmlReader.Create(new
StringReader(@"<MyClass><Height>3</Height><Width>7</Width></
MyClass>")))
        {
            MyClass newStyle = (MyClass)xs.ReadObject(xr);
            Console.WriteLine(newStyle);
        }
    }
}
0
4/11/2008 8:50:47 AM
Reply:

Similar Artilces:

XML that one of its elements has line break.
Hello, I am using access as my database, One of my columns is memo field, so it has sevral line at its context. Can I convert line break to something readable in XML ? Is there any function for that ? Thanks :) Same thing. Any character, be it ascii or unicode has it's place or number. If Access bitches, it is Access and not Calculus. "Mr. x" <a@b.com> wrote in message news:uaYLyYxeDHA.4024@TK2MSFTNGP11.phx.gbl... > Hello, > I am using access as my database, > One of my columns is memo field, so it has sevral line at its context. > Can I convert line b...

New CNBC site--is Money 7 portfolio compatible
I just registered for the new CNBC site and it mentions portfolio. My question is will money7 portfolio be compatible with this site and if not why? I think I know the answer but I just cant figure it out. Why would MS go to all the trouble to update the msnmoney site and create a new site and not make them compatible with their latest version of the only software they are supporting going forward? I attended a recent meeting where Vista and the new Office were demoed. I asked about Money but no one was aware of the problems. I have asked this question before but I just wanted to ...

XML Insert data C# ASP.net 2.0 Need to know how to insert by speci
Hello, I have the following XML Schema: <?xml version="1.0" encoding="utf-8"?> <Schedule> <Day Name="Monday"> </Day> <Day Name="Tuesday"> </Day> <Day Name="Wednesday"> </Day> <Day Name="Thursday"> </Day> <Day Name="Friday"> </Day> <Day Name="Saturday"> </Day> <Day Name="Sunday"> </Day> </Schedule> I want users to be able to input the following tiomeblocks for a scheduling s...

XML excel file
Hello!!! I need to insert an image file in this XML Excel file. How can I do it? <?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> <Last...

XML Flexibility
is it possible to create a flexible dtd or xsd that allows new nodes to be added to the xml document that still conforms to the dtd or xsd? Chris Fink wrote: > is it possible to create a flexible dtd or xsd that allows new nodes to be > added to the xml document that still conforms to the dtd or xsd? Sure. Take a look at http://www.w3.org/TR/xmlschema-0/#any -- Oleg Tkachenko [XML MVP, MCP] http://blog.tkachenko.com ...

Drawing in VBA
I have “inherited” a number of legacy worksheets that use, I believe, the pre Excel 97 via VBA drawing object model to plot complex diagrams on a number of sheets. These work perfectly in all versions of Excel up and to Excel 2003, but now give problems when running under Excel 2007 (although the VBA compiles OK) . In Excel 2007 the positioning and rotation of the arcs (and to some extent other drawing items). are totally different in Xl 2007 A simply example of the code I have is show below: Sub DrawArc() With ActiveSheet.Arcs.Add(10, 10, 200, 200) With...

How to change the sequence of the Nested DataRelation XML elements in VB .NET
Hi, I create a Dataset to link three tables in my Access database in VB .NET. The three tables are [Table_1], [Table_2], [Table_3]. I then create 2 DataRelations, Relation_1 links [Table_1] and [Table_2] using ("LinkID_1_2") field that exists in both tables and Relation_2 links [Table_2] and [Table_3] using ("LinkID_2_3") field. I set the nested property of both the DataRelations to True so that the output will be nested. I then use WriteXML to output the dataset to a StreamWriter. The vb code is follow: '~~~~~~~~~~~~~~~~~ vb code Start ~~~~~~~~~~~~~~~~~~~~~...

How to Supress XML Processor instruction
Is there a way to suppress the rendering of the xml processor instruction when using the XmlSerializer? I do not want "<?xml version="1.0"?>" to be written out. Also, do classes generated from XSD.EXE care about the value of "elementFormDefault". I don't see anywhere in a class any references to this attribute. I need the elements to be qualified. Kevin For your first question, one way to do it is to derive from System.Xml.XmlTextWriter, and simply provide a "null" implementation of WriteStartDocument(). public class XmlTextWriterFor...

Write XML to File while reading
I'm reading in an XML file from the server using XmlTextReader in C# like so: XmlTextReader xr = new XmlTextReader(url); while(xr.Read()) { //parse the xml file here } Now then, I need to also save this file to the local file system and I should be able to do this at the same time I'm reading the file with XmlTextReader, right? I figured I don't really need to use XMLTextWriter since the file is already in XML format, so I tried StreamWriter and then tried to write the file in the while loop one line at a time using 'streamwriter.write(xr.Name)' but that's...

XML Packets
Hi: I am working on a Client Server application sending XML messages through TCP/IP connection. I need to construct XML packets and send it through TCP/IP to the client from the server. I am looking for code how to construct XML packets enclosing the XML text and send it to the server... Any help will be appreciated. Thanks in advance.. Kapil Shah Kapil Shah wrote: > I am working on a Client Server application sending XML > messages through TCP/IP connection. I need to construct > XML packets and send it through TCP/IP to the client from > the server. > I a...

Xml // Reading Element Value // Namespace issue // XPathExpression XmlNamespaceManager
Ok, my xml inability shows itself once again. Thanks for any help. Below I have some xml and some code for trying to get the "Publish_Date" element value. I've tried 4 different ways to get it. (If you uncomment the lines in the code seen here, you can see the ways I've tried to get the value) theOneImGonnaTry = myNameSpaceNameLocalName1 + ":"; theOneImGonnaTry = myNameSpaceNameLocalName2 + ":"; theOneImGonnaTry = myNameSpaceNameLocalName3 + ":"; theOneImGonnaTry = string.Empty; (The code seen above makes more sense when you look at th...

Simple XML Log
I want to receive an XML document via an aspx page and log the raw xml to a text file. I've been looking at this for a while and can't work out how to do it. Can someone tell me how to grab the raw xml text (once I've got the text I can do the logging bit) Thanks HHoulston wrote: > I want to receive an XML document via an aspx page and log the raw > xml to a text file. I've been looking at this for a while and can't > work out how to do it. Can someone tell me how to grab the raw xml > text (once I've got the text I can do the logging bit)? Assumin...

publisher to word compatibility
I've windows xp and publisher 2003. I tried to use a publication in "Quick Books Customer Manager" but cannot be read because it is not in MS Word. How do I create a publication in MS Publisher that can be read as a Word doc? If not possible and I need to install Word, will any version do and still be compatible with MS Publisher? I'm on a tight budget and would prefer to save some$$. Thanks. You cannot create a publication in Publisher to make it look like a Word doc - no way. Any version later than Word 2000 should be acceptable. Make sure you install all the service...

Problem serializing type System.Xml.XmlElement
I have written a little application that can grab part of a page from a web site. I then want to take this result and be able to serialize it so that it can be stored as XML. I am storing these "ResultNodes" as System.Xml.XmlElements but when I try and serialize (serialise) my result object I get the following exception: "System.InvalidOperationException" - "There was an error generating the XML document" "The type System.Xml.XmlElement may not be used in this context." at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o...

Reading / Writing XML To / From object model (without XMLDocument?
Hello, My program is being sent a large XML file, anywhere between 500k - 1MB. Of the entire file, I need to allow a user to view/edit approximately 5% of it. To make matters a bit more complicated, there are occasions where the program needs to load up around 5 instances of these documents. I'm trying to find the most efficient and non-complicated way to do this. My initial idea was to load the XML file into a DOM and get/set the element values via a dom. This is trivial to do, however the problem with this is each 500k instance of this document consumes ~3MB of memory. I s...

Excel 2007 how to create charts compatible with 2003?
Excel 2007 gives a warning that colours etc are not compatible with Excel 2003. Is there a way of creating charts - perhaps by defining a new gallery - that does not show that prompt? Of course, one could create it in 2003, but this is a question for when Excel 2007 is being used. ...

XML Serialization Problem with jagged array
I have the following class that declares a jagged array named procedimentosRealizadosField()(). When I try to deserialize an XML file into an object of this class all fields are loaded correctly, except for the procedimentosRealizadosField()() which returns nothing. Previously, I changed the declaration of the method from : <System.Xml.Serialization.XmlArrayItemAttribute("procedimentosRevisao", GetType(ct_procedimentoRevisaoProcedimentosRevisao), IsNullable:=False)> _ to : <System.Xml.Serialization.XmlArrayItemAttribute("procedimentosRevisao", GetType(ct_proc...

How parse XML values from a string?
I have a string (see below) that I want to parse out the values. As you can see, some are element-based and some are attribute-based. <METADATA version="Format5"><TITLE value="Adrenaline Rush"/><DESCRIPTION>Take a thrilling look at the world of skydiving and base jumping - parachuting from a building, a bridge or a cliff. With breathtaking views of skydiving over the Florida Keys, the Mojave Desert and the magnificent Fjords of Norway, this giant-screen experience explores the psychological and physiological forces behind risk-tasking and the physi...

question about xml serilization
hello, This is my sample (simplified): public class Binom { [XmlAttribute("range")] public string _Value; [XmlAttribute("name")] public string Label; } public class Property { [XmlAttribute("name")] public string propertyName; public Binom DefaultAttribute; } Property serialize as: <Properties name="foo"> <DefaultAttribute value="123456789" name="range" /> </Properties > Is is possible to get rather: <foo range="123456789"/> or eventualy: <Properties name="foo"> &l...

how do i map an excel column to an XML element
How do i map an entire column of data in an excel spreadsheet to an XML data element in the XML source Task Pane? I want to export the data in my spreadsheet so that every row in my spreadsheet is an XML record and every cell in the row is a sub element ...

Exporting from XMLReader to an XML file
Hello, I have an XmlReader object containg some Xml code. I would like to export this document from the reader to an Xml file. How to do this? Thanks for any hints, Leszek Taratuta Below there is the code I'm using: string myXmlQuery = "SELECT 1 AS Tag, NULL AS Parent, [Filename] AS [Content!1!Filename!element], [Caption] AS [Content!1!Caption!element], [Content] AS [Content!1!!CDATA] FROM Content FOR XML EXPLICIT"; SqlConnection myConnection = new SqlConnection("data source=WEBSERVER;database=myDB;user id=;password=); try { myConnection.Open(); SqlCommand myCommand...

eConnect
In eConnect, I tried adding an additional XML node to the existing XML schema. I like to have these to be added in line item level. When I tried this, it worked fine when I added a node (along with a procedure in db) at the header level. But it fails to perform at line item level. Please help me with the steps to achieve the same. Thanks in advance. ...

Excel to XML: Need some help fine tuning a macro
Hey all, I've downloaded a Macro http://meadinkent.co.uk/ and have been editing it get the exported XML to appear as required, however I can't seem to get the 2 of my fields to display correctly. There are two fields which have numbers in but are formatted as text because I do not want them rounded up. One cell has -0.08162498 in it and in the exported XML doesn't even appear. Another cell has 51.51891794 in it and in the exported XML appears as 52. My question is how can I get the information to appear as I've typed it in rather then rounding it? I have cha...

How to transform XML by using XSLT
Hi I need to know how to transform a XML file by using a XSLT file. Consider the following XML file <?xml version="1.0" encoding="UTF-8" standalone="yes"?><LogFile><Dog TimeStamp="16.02.2004 10:04:48" ModifiedBy="Smith, Geoff"><NameOfDog>Fido</NameOfDog><Weight>10</Weight></Dog><Dog TimeStamp="16.02.2004 10:05:24" ModifiedBy="Scott, Al"><Color>Black</Color><Weight>12</Weight></Dog></LogFile By the magic of some XSLT file I want the follo...

C# and XML Document
I am having problems with the following code. I am able to open the xml document and read it into memory and if I step through the code and look at the variables, I can see that the XML document is correct. What is happening is that what is being returned into TableName is "System.Xml.XmlElement" If I look at the variables in the autos window, I can see the following in InnerXML, <FOLDERNAME>Member</FOLDERNAME> etc. Folders = Doc.SelectSingleNode("SCHEMA").SelectSingleNode("FOLDER").SelectSingleNode("SUBFOLDERS").ChildNodes; TableLi...