带有命名空间的 C# XML 反序列化 [英] C# XML deserialization with namespace
问题描述
我有 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>
我正在尝试反序列化:
[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; }
}
}
}
然而,它将 CubeRootEl 反序列化为空列表.如果我从 XML 中删除 namspaces,那么它反序列化成功.我究竟做错了什么?我尝试在代码中向 CubeRootEl 添加空命名空间,但也没有成功.
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;
}
推荐答案
你有几个问题:
您没有为属性
public List
.如果未指定属性的命名空间,指定命名空间.CubeRootEl XmlSerializer
假定它与包含元素位于同一命名空间,在这种情况下为"http://www.gesmes.org/xml/2002-08-01"
.但是
元素不在这个命名空间中,因为它们没有"gesmes:"
前缀.
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.
您的 XML 具有默认命名空间声明 xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
.因此
元素实际上在这个命名空间中.
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.
Sender
不是一个简单的字符串值元素,它有一个嵌套元素
.
Sender
is not a simple string-valued element, it has a nested element <gesmes:name>European Central Bank</gesmes:name>
.
修复这三个问题可以反序列化您的 XML:
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; }
}
}
}
这篇关于带有命名空间的 C# XML 反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!