Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Deserialising derived classes using XmlAttributeOverrides

Deserialising derived classes using XmlAttributeOverrides

Scheduled Pinned Locked Moved C#
xmltutorialcsharpdatabaselinq
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Clive D Pottinger
    wrote on last edited by
    #1

    Hello again. I've painted myself into a corner once more - this time with a different colour of paint! I am trying to understand how to use XmlAttributeOverrides() to control the deserialisation of an XML file, but I can't seem to figure out how to tell it what I want to do. I have created a running example. Using this XML:

    <?xml version="1.0" encoding="utf-8"?>
    <orchestra>
    <bloweythingy name="flute" reed="false"/>
    <bloweythingy name="oboe" reed="true"/>
    <hitythingy name="tympani" keys="false"/>
    <hitythingy name="piano" keys="true"/>
    </orchestra>

    I would like to create an Orchestra object that contains 2 objects of class Woodwind (representing the contents of the bloweything elements) and 2 of class Percussion (representing hitythingy content). Both Woodwind and Percussion are derived from class Instrument. Additionally, I would like to do this without decorating the classes with [XmlElement] attributes so that, later on, I will be able to programatically add new Instrument types. To do this, I created a "registry" to which the code will be able to add an XML tag name and the class to be used to represent the data in that tag. Eventually, the registry will cache the XmlSerializer objects to be used with each tag... but for now the serialisers are created on the fly. Here is the code to try and do this:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;

    namespace Deserialising
    {
    class ExampleA
    {
    static void Main(string[] args)
    {
    XmlSerializer iniSerializer = new XmlSerializer(typeof(Orchestra));
    TextReader iniReader = new StreamReader("C:\\Temp\\ExampleOrchestra.xml");
    try
    {
    Orchestra DuchyOfGrandFenwickPhilharmonic = (Orchestra)iniSerializer.Deserialize(iniReader);
    }
    catch (Exception ex)
    {
    while (ex != null)
    {
    Console.WriteLine(ex.Message);
    ex = ex.InnerException;
    }
    Console.ReadKey();
    }
    iniReader.Close();
    }
    }

    \[XmlRoot("orchestra")\]
    public class Orc
    
    N H 2 Replies Last reply
    0
    • C Clive D Pottinger

      Hello again. I've painted myself into a corner once more - this time with a different colour of paint! I am trying to understand how to use XmlAttributeOverrides() to control the deserialisation of an XML file, but I can't seem to figure out how to tell it what I want to do. I have created a running example. Using this XML:

      <?xml version="1.0" encoding="utf-8"?>
      <orchestra>
      <bloweythingy name="flute" reed="false"/>
      <bloweythingy name="oboe" reed="true"/>
      <hitythingy name="tympani" keys="false"/>
      <hitythingy name="piano" keys="true"/>
      </orchestra>

      I would like to create an Orchestra object that contains 2 objects of class Woodwind (representing the contents of the bloweything elements) and 2 of class Percussion (representing hitythingy content). Both Woodwind and Percussion are derived from class Instrument. Additionally, I would like to do this without decorating the classes with [XmlElement] attributes so that, later on, I will be able to programatically add new Instrument types. To do this, I created a "registry" to which the code will be able to add an XML tag name and the class to be used to represent the data in that tag. Eventually, the registry will cache the XmlSerializer objects to be used with each tag... but for now the serialisers are created on the fly. Here is the code to try and do this:

      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Schema;
      using System.Xml.Serialization;

      namespace Deserialising
      {
      class ExampleA
      {
      static void Main(string[] args)
      {
      XmlSerializer iniSerializer = new XmlSerializer(typeof(Orchestra));
      TextReader iniReader = new StreamReader("C:\\Temp\\ExampleOrchestra.xml");
      try
      {
      Orchestra DuchyOfGrandFenwickPhilharmonic = (Orchestra)iniSerializer.Deserialize(iniReader);
      }
      catch (Exception ex)
      {
      while (ex != null)
      {
      Console.WriteLine(ex.Message);
      ex = ex.InnerException;
      }
      Console.ReadKey();
      }
      iniReader.Close();
      }
      }

      \[XmlRoot("orchestra")\]
      public class Orc
      
      N Offline
      N Offline
      N a v a n e e t h
      wrote on last edited by
      #2

      cpotting wrote:

      XmlSerializer iniSerializer = new XmlSerializer(typeof(Orchestra));

      It looks like you are using a wrong overload of XmlSerializer constructor. I can't see anywhere in your code where XmlSerializer is getting your XmlAttributeOverrides object. Try with this[^] overload instead.

      Navaneeth How to use google | Ask smart questions

      C 1 Reply Last reply
      0
      • C Clive D Pottinger

        Hello again. I've painted myself into a corner once more - this time with a different colour of paint! I am trying to understand how to use XmlAttributeOverrides() to control the deserialisation of an XML file, but I can't seem to figure out how to tell it what I want to do. I have created a running example. Using this XML:

        <?xml version="1.0" encoding="utf-8"?>
        <orchestra>
        <bloweythingy name="flute" reed="false"/>
        <bloweythingy name="oboe" reed="true"/>
        <hitythingy name="tympani" keys="false"/>
        <hitythingy name="piano" keys="true"/>
        </orchestra>

        I would like to create an Orchestra object that contains 2 objects of class Woodwind (representing the contents of the bloweything elements) and 2 of class Percussion (representing hitythingy content). Both Woodwind and Percussion are derived from class Instrument. Additionally, I would like to do this without decorating the classes with [XmlElement] attributes so that, later on, I will be able to programatically add new Instrument types. To do this, I created a "registry" to which the code will be able to add an XML tag name and the class to be used to represent the data in that tag. Eventually, the registry will cache the XmlSerializer objects to be used with each tag... but for now the serialisers are created on the fly. Here is the code to try and do this:

        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Linq;
        using System.Text;
        using System.Xml;
        using System.Xml.Schema;
        using System.Xml.Serialization;

        namespace Deserialising
        {
        class ExampleA
        {
        static void Main(string[] args)
        {
        XmlSerializer iniSerializer = new XmlSerializer(typeof(Orchestra));
        TextReader iniReader = new StreamReader("C:\\Temp\\ExampleOrchestra.xml");
        try
        {
        Orchestra DuchyOfGrandFenwickPhilharmonic = (Orchestra)iniSerializer.Deserialize(iniReader);
        }
        catch (Exception ex)
        {
        while (ex != null)
        {
        Console.WriteLine(ex.Message);
        ex = ex.InnerException;
        }
        Console.ReadKey();
        }
        iniReader.Close();
        }
        }

        \[XmlRoot("orchestra")\]
        public class Orc
        
        H Offline
        H Offline
        Henry Minute
        wrote on last edited by
        #3

        Yeah, and you've misspelled hittythingy, as well!! :-D

        Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

        C 1 Reply Last reply
        0
        • N N a v a n e e t h

          cpotting wrote:

          XmlSerializer iniSerializer = new XmlSerializer(typeof(Orchestra));

          It looks like you are using a wrong overload of XmlSerializer constructor. I can't see anywhere in your code where XmlSerializer is getting your XmlAttributeOverrides object. Try with this[^] overload instead.

          Navaneeth How to use google | Ask smart questions

          C Offline
          C Offline
          Clive D Pottinger
          wrote on last edited by
          #4

          Thanks Navaneeth. To answer point about where the XmlSerializer was getting my XmlAttributesOverrides object: the idea was to have the Orchestra class deserialise each <bloweythingy> and <hittythingy> tag as it encountered them. To do this Orchestra implement IXmlSerializable and the deserialisation was done inside the ReadXml() method. So the XmlAttributeOverrides were being assigned to the XmlSerializer ts in the Orchestra class, not the iniSerializer in Main. That was the idea. But after carefully examining the example you linked to, I now realise my mistake: I misunderstood the meaning of each parameter in the XmlAttributeOverrides.Add() method. I had written

          instrumentXmlOverrides.Add(typeof(Instrument), kvp.Value.Name, xa);
          = when told to deserialise an Instrument [parm 1], if you run across a <bloweythingy> tag [parm2] apply the rules in xa (deserialise the <bloweythingy> tags into Woodwinds) [parm 3]

          I thought the first 2 parms were the class being deserialised and the "alternate" tagname for that class (Instrument and <bloweythingy>). In reality they are the class being deserialised and the tagname/class name of a property of that class. I should have been trying do this:

          instrumentXmlOverrides.Add(typeof(Orchestra), "Instrument", xa);
          = when told to deserialise an Orchestra [parm 1], where you would normally expect an Instrument tag [parm2] apply the rules in xa (which should include both alternate tagnames for Instrument [bloweythingy and hittythingy] and their classes [Woodwinds and Percussion]) [parm 3]

          In order to do that, I had to reorganise my code so that the overrides were all constructed before ever trying to deserialise Orchestra. That allowed me to remove the IXmlSerializable interface from Orchestra and simplify the code. Thanks again, Navaneeth. I can now move ahead with the actual application I am writing.

          Clive Pottinger Victoria, BC

          N 1 Reply Last reply
          0
          • H Henry Minute

            Yeah, and you've misspelled hittythingy, as well!! :-D

            Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

            C Offline
            C Offline
            Clive D Pottinger
            wrote on last edited by
            #5

            Henry Minute wrote:

            Yeah, and you've misspelled hittythingy, as well!! Big Grin

            I checked AskOford.com first - but appearently, it is not a term in common usage in England. So I was left to guess. :-O I have corrected my code ;)

            Clive Pottinger Victoria, BC

            1 Reply Last reply
            0
            • C Clive D Pottinger

              Thanks Navaneeth. To answer point about where the XmlSerializer was getting my XmlAttributesOverrides object: the idea was to have the Orchestra class deserialise each <bloweythingy> and <hittythingy> tag as it encountered them. To do this Orchestra implement IXmlSerializable and the deserialisation was done inside the ReadXml() method. So the XmlAttributeOverrides were being assigned to the XmlSerializer ts in the Orchestra class, not the iniSerializer in Main. That was the idea. But after carefully examining the example you linked to, I now realise my mistake: I misunderstood the meaning of each parameter in the XmlAttributeOverrides.Add() method. I had written

              instrumentXmlOverrides.Add(typeof(Instrument), kvp.Value.Name, xa);
              = when told to deserialise an Instrument [parm 1], if you run across a <bloweythingy> tag [parm2] apply the rules in xa (deserialise the <bloweythingy> tags into Woodwinds) [parm 3]

              I thought the first 2 parms were the class being deserialised and the "alternate" tagname for that class (Instrument and <bloweythingy>). In reality they are the class being deserialised and the tagname/class name of a property of that class. I should have been trying do this:

              instrumentXmlOverrides.Add(typeof(Orchestra), "Instrument", xa);
              = when told to deserialise an Orchestra [parm 1], where you would normally expect an Instrument tag [parm2] apply the rules in xa (which should include both alternate tagnames for Instrument [bloweythingy and hittythingy] and their classes [Woodwinds and Percussion]) [parm 3]

              In order to do that, I had to reorganise my code so that the overrides were all constructed before ever trying to deserialise Orchestra. That allowed me to remove the IXmlSerializable interface from Orchestra and simplify the code. Thanks again, Navaneeth. I can now move ahead with the actual application I am writing.

              Clive Pottinger Victoria, BC

              N Offline
              N Offline
              N a v a n e e t h
              wrote on last edited by
              #6

              Great. Happy to help :thumbsup:

              Navaneeth How to use google | Ask smart questions

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups