C# XML deserialization with namespace

风格不统一 提交于 2021-02-10 12:13:47

问题


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; 
} 

回答1:


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; }
        }
    }
}


来源:https://stackoverflow.com/questions/34331860/c-sharp-xml-deserialization-with-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!