3

I have XML:

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time='2015-12-16'>
            <Cube currency='USD' rate='1.0933'/>
            <Cube currency='JPY' rate='133.18'/>
        </Cube>
    </Cube>
</gesmes:Envelope>

which I'm trying to deserialize with:

[XmlRoot("Envelope", Namespace = EcbNameSpace)]
public class EcbEnvelope
{
    const string EcbNameSpace = "http://www.gesmes.org/xml/2002-08-01";

    [XmlElement("Sender", Namespace = EcbNameSpace)]
    public string EcbSender { get; set; }

    [XmlElement("subject", Namespace = EcbNameSpace)]
    public string EcbSubject { get; set; }

    [XmlArray("Cube")]
    [XmlArrayItem("Cube")]
    public List<CubeRoot> CubeRootEl { get; set; }

    public class CubeRoot
    {
        [XmlAttribute("time")]
        public string Time { get; set; }

        [XmlElement("Cube")]
        public List<CubeItem> CubeItems { get; set; }

        public class CubeItem
        {
            [XmlAttribute("rate")]
            public string RateStr { get; set; }

            [XmlIgnore]
            public decimal Rate
            {
                get { return decimal.Parse(RateStr); }
            }

            [XmlAttribute("currency")]
            public string Currency { get; set; }
        }
    }   
}

However, it deserializes CubeRootEl as empty list. If I remove namspaces from XML, then it deserializes successfully. What am I doing wrong? I tried adding empty namespaces to CubeRootEl in code, but also unsuccessfully.

Here's the code used for deserialization:

var serializer = new XmlSerializer(typeof(EcbEnvelope)); 
using (var streamReader = new StreamReader(pathToFile)) 
    var a = serializer.Deserialize(streamReader) as EcbEnvelope; 
} 
2
  • What code do you use for deserialization? Commented Dec 17, 2015 at 10:20
  • var serializer = new XmlSerializer(typeof(EcbEnvelope)); using (var streamReader = new StreamReader(pathToFile)) { var a = serializer.Deserialize(streamReader) as EcbEnvelope; } Commented Dec 17, 2015 at 10:22

1 Answer 1

2

You have a few issues:

  1. You do not specify a namespace for the property public List<CubeRoot> CubeRootEl. When a namespace for a property is not specified, XmlSerializer assumes it to be in the same namespace as the containing element, which would in this case be "http://www.gesmes.org/xml/2002-08-01". But the <Cube> elements are not in this namespace since they do not have the "gesmes:" prefix.

  2. Your XML has a default namespace declaration xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref". Thus the <Cube> elements are actually in this namespace.

  3. Sender is not a simple string-valued element, it has a nested element <gesmes:name>European Central Bank</gesmes:name>.

Fixing these three issues allows your XML to be deserialized:

[XmlRoot("Envelope", Namespace = GesmesNameSpace)]
public class EcbEnvelope
{
    public const string GesmesNameSpace = "http://www.gesmes.org/xml/2002-08-01";
    public const string EcbNameSpace = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";

    [XmlElement("Sender", Namespace = GesmesNameSpace)]
    public EcbSender Sender { get; set; }

    [XmlElement("subject", Namespace = GesmesNameSpace)]
    public string EcbSubject { get; set; }

    [XmlArray("Cube", Namespace = EcbNameSpace)]
    [XmlArrayItem("Cube")]
    public List<CubeRoot> CubeRootEl { get; set; }

    public class EcbSender
    {
        [XmlElement("name")]
        public string Name { get; set; }
    }

    public class CubeRoot
    {
        [XmlAttribute("time")]
        public string Time { get; set; }

        [XmlElement("Cube")]
        public List<CubeItem> CubeItems { get; set; }

        public class CubeItem
        {
            [XmlAttribute("rate")]
            public string RateStr { get; set; }

            [XmlIgnore]
            public decimal Rate
            {
                get { return decimal.Parse(RateStr); }
            }

            [XmlAttribute("currency")]
            public string Currency { get; set; }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.