3

I receive from two different systems an xml which I have to deserialise with c#. Both xml should be the same but unfortunately they are slightly different and there is no way for me take influence on the systems how they create the xml.

xml1

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<alarm>
  <alarmDetails>
    <dateTime>20180906-121451</dateTime>
  </alarmDetails>
  <deviceDetails>
    <deviceType>abacaxi</deviceType>
  </deviceDetails>
  <position>
    <altitude>1000</altitude>
  </position>
</alarm>

xml2

<?xml version="1.0" encoding="utf-8"?>
<alarm xmlns="http://alarm.com/xsd">
  <alarmDetails>
    <dateTime>20180906-114818</dateTime>
  </alarmDetails>
  <deviceDetails>
    <deviceType>tapioca</deviceType>
  </deviceDetails>
  <position>
    <altitude>1000</altitude>
  </position>
</alarm>

(xml 2 has an additional attribut on the alarm-tag)

I tried to deserialize this with the following:

code

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Alarm));
            StreamReader stream = new StreamReader("C:\\Temp\\xml1.xml");
            Alarm alarmmessage = (Alarm)serializer.Deserialize(stream);
        }
    }


    [XmlRoot(ElementName = "alarmDetails")]
    public class AlarmDetails
    {
        [XmlElement(ElementName = "dateTime")]
        public string DateTime { get; set; }
    }

    [XmlRoot(ElementName = "deviceDetails")]
    public class DeviceDetails
    {
        [XmlElement(ElementName = "deviceType")]
        public string DeviceType { get; set; }
    }

    [XmlRoot(ElementName = "position")]
    public class Position
    {
        [XmlElement(ElementName = "altitude")]
        public string Altitude { get; set; }
    }

    [XmlRoot(ElementName = "alarm")]
    public class Alarm
    {
        [XmlElement(ElementName = "alarmDetails")]
        public AlarmDetails AlarmDetails { get; set; }
        [XmlElement(ElementName = "deviceDetails")]
        public DeviceDetails DeviceDetails { get; set; }
        [XmlElement(ElementName = "position")]
        public Position Position { get; set; }
    }
}

This works perfect for xml1 but for xml2 I get this Error:

Error

System.InvalidOperationException
Message=There is an error in XML document (2,2).
Inner Exception 1:
InvalidOperationException: <alarm xmlns='http://alarm.com/xsd'> was not expected.

Possible solution

All this did not work..

XmlRootAttribute

From: {" was not expected.} Deserializing Twitter XML

I ended up with this modification:

static void Main(string[] args)
{
    XmlRootAttribute xRoot = new XmlRootAttribute();
    xRoot.ElementName = "alarm";
    xRoot.IsNullable = true;
    XmlSerializer serializer = new XmlSerializer(typeof(Alarm), xRoot);
    StreamReader stream = new StreamReader("C:\\Temp\\xml2.xml");
    Alarm alarmmessage = (Alarm)serializer.Deserialize(stream);
}

Get the same Error as mentioned above.

IsNullable=true to XmlRoot

From: {" was not expected.} Deserializing Twitter XML

[XmlRoot(ElementName = "alarm", IsNullable = true)]
public class Alarm
{ 
    [XmlElement(ElementName = "alarmDetails")]
    public AlarmDetails AlarmDetails { get; set; }
    [XmlElement(ElementName = "deviceDetails")]
    public DeviceDetails DeviceDetails { get; set; }
    [XmlElement(ElementName = "position")]
    public Position Position { get; set; }
}

Same Error as mentioned above.

XmlAttributeOverrides

From: Ignore a property during xml serialization but not during deserialization

static void Main(string[] args)
{
    XmlAttributeOverrides overrides = new XmlAttributeOverrides();
    XmlAttributes attribs = new XmlAttributes();
    attribs.XmlIgnore = true;
    attribs.XmlElements.Add(new XmlElementAttribute("alarm"));
    overrides.Add(typeof(Alarm), "alarm", attribs);
    XmlSerializer serializer = new XmlSerializer(typeof(Alarm), overrides);
    StreamReader stream = new StreamReader("C:\\Temp\\xml2.xml");
    Alarm alarmmessage = (Alarm)serializer.Deserialize(stream);
}

Still same Error as mentioned above.

Suggestion?

What else could I try to make this work? Is there some working way to ignore the xmlns-Attribut?

John Thomas
  • 88
  • 1
  • 8
CaptainInler
  • 157
  • 1
  • 9
  • `xmlns="http://alarm.com/xsd"` is a XML default namespace declaration, so this might work for you: [Can I make XmlSerializer ignore the namespace on deserialization?](https://stackoverflow.com/q/870293). – dbc Sep 25 '18 at 23:03
  • `XmlSerializationHelper.LoadFromXmlAsType(this TextReader textReader)` from [this answer](https://stackoverflow.com/a/50005174/3744182) might also work for you. – dbc Sep 25 '18 at 23:11
  • @dbc Thanks for your reply. [Can I make XmlSerializer ignore the namespace on deserialization?](https://stackoverflow.com/questions/870293/can-i-make-xmlserializer-ignore-the-namespace-on-deserialization) did work. Do you want to write an answer based on this so I can mark it as the solution? I didn't realy understand `XmlSerializationHelper.LoadFromXmlAsType(this TextReader textReader)` and did not get it to work.. – CaptainInler Sep 26 '18 at 07:58
  • I can mark this as a duplicate. – dbc Sep 26 '18 at 08:00

0 Answers0