[英]XML deserialization with array inside a class
我正在尝试反序列化一串XML数据。 但是我没有在反序列化函数返回的对象中找回数据。
以下是类定义:
[XmlType("STATE-COUNTY-RECORDS")]
public class StateCountyRecords
{
[XmlElement("TOTAL")]
public int Total { get; set; }
[XmlElement("LIMIT")]
public int Limit { get; set; }
[XmlElement("OFFSET")]
public int Offset { get; set; }
[XmlArray("STATE-COUNTY-ARRAY"), XmlArrayItem("STATE-COUNTY")]
public StateCounty[] StateCountyArray { get; set; }
public StateCountyRecords() {}
public StateCountyRecords(int total, int limit, int offset, int[] id, string[] fips_code, string[] state, string[] name)
{
Total = total;
Limit = limit;
Offset = offset;
var count = id.Length;
StateCountyArray = new StateCounty[count];
for (int i = 0; i < count; i++)
{
StateCountyArray[i] = new StateCounty(id[i], fips_code[i], state[i], name[i]);
}
}
}
public class StateCounty
{
[XmlElement("ID")]
public int Id { get; set; }
[XmlElement("FIPS-CODE")]
public string Fips_Code { get; set; }
[XmlElement("STATE")]
public string State { get; set; }
[XmlElement("NAME")]
public string Name { get; set; }
public StateCounty(int id, string fips_code, string state, string name)
{
Id = id;
Fips_Code = fips_code;
State = state;
Name = name;
}
public StateCounty() { }
}
这是xml字符串数据:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<STATE-COUNTY-FILE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
<STATE-COUNTY-RECORDS>
<TOTAL>3314</TOTAL>
<LIMIT>10</LIMIT>
<OFFSET>0</OFFSET>
<STATE-COUNTY-ARRAY>
<STATE-COUNTY>
<ID>1</ID>
<FIPS-CODE>01000</FIPS-CODE>
<STATE>AL</STATE>
<NAME>Alabama</NAME>
</STATE-COUNTY>
<STATE-COUNTY>
<ID>2</ID>
<FIPS-CODE>01001</FIPS-CODE>
<STATE>AL</STATE>
<NAME>Autauga</NAME>
</STATE-COUNTY>
<STATE-COUNTY>
<ID>3</ID>
<FIPS-CODE>01003</FIPS-CODE>
<STATE>AL</STATE>
<NAME>Baldwin</NAME>
</STATE-COUNTY>
</STATE-COUNTY-ARRAY>
</STATE-COUNTY-RECORDS>
</STATE-COUNTY-FILE>
以下是反序列化xml字符串的函数:
public static StateCountyRecords DeserializeStateCountyData(string xmlString)
{
XmlSerializer mySerializer = new XmlSerializer(typeof(StateCountyRecords), new XmlRootAttribute("STATE-COUNTY-FILE"));
using (XmlReader myXmlReader = XmlReader.Create(new StringReader(xmlString)))
{
StateCountyRecords rslt;
rslt = (StateCountyRecords)mySerializer.Deserialize(myXmlReader);
}
}
}
我得到的rslt不包含Total和Limit的数据,Offset all为0,StateCountyArray为null。 我没有得到任何错误。 我通过以下方式确保xml有效:
if (myXmlReader.CanResolveEntity && myXmlReader.CanReadValueChunk && myXmlReader.CanReadBinaryContent)
rslt = (StateCountyRecords)mySerializer.Deserialize(myXmlReader);
我想知道我的类定义的XmlElement和XML文件之间是否存在不匹配。
您的问题是您的XML有一个外部元素,在您的数据模型中没有考虑,即<STATE-COUNTY-FILE>
元素:
<STATE-COUNTY-FILE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<STATE-COUNTY-RECORDS>
<!-- Various elements under StateCountyRecords -->
</STATE-COUNTY-RECORDS>
</STATE-COUNTY-FILE>
由于数据模型的根是StateCountyRecords
,因此没有任何内容与此最外层元素相对应。 您尝试使用new XmlRootAttribute("STATE-COUNTY-FILE")
解决此问题,但是这只会重命名外部元素,而不是添加额外的嵌套级别。
相反,您需要为此目的引入外部容器POCO:
[XmlType("STATE-COUNTY-FILE")]
public class StateCountyFile
{
[XmlElement("STATE-COUNTY-RECORDS")]
public StateCountyRecords StateCountyRecords { get; set; }
}
并反序列化如下:
public static StateCountyRecords DeserializeStateCountyData(string xmlString)
{
var mySerializer = new XmlSerializer(typeof(StateCountyFile));
using (var myXmlReader = XmlReader.Create(new StringReader(xmlString)))
{
var rslt = (StateCountyFile)mySerializer.Deserialize(myXmlReader);
return rslt.StateCountyRecords;
}
}
或者,您可以手动前进XmlReader
直到遇到名为<STATE-COUNTY-RECORDS>
的元素,并反序列化:
public static StateCountyRecords DeserializeStateCountyData(string xmlString)
{
return XmlTypeExtensions.DeserializeNestedElement<StateCountyRecords>(xmlString);
}
使用扩展方法:
public static class XmlTypeExtensions
{
public static T DeserializeNestedElement<T>(string xmlString)
{
var mySerializer = new XmlSerializer(typeof(T));
var typeName = typeof(T).XmlTypeName();
var typeNamespace = typeof(T).XmlTypeNamespace();
using (var myXmlReader = XmlReader.Create(new StringReader(xmlString)))
{
while (myXmlReader.Read())
if (myXmlReader.NodeType == XmlNodeType.Element && myXmlReader.Name == typeName && myXmlReader.NamespaceURI == typeNamespace)
{
return (T)mySerializer.Deserialize(myXmlReader);
}
return default(T);
}
}
public static string XmlTypeName(this Type type)
{
var xmlType = type.GetCustomAttribute<XmlTypeAttribute>();
if (xmlType != null && !string.IsNullOrEmpty(xmlType.TypeName))
return xmlType.TypeName;
return type.Name;
}
public static string XmlTypeNamespace(this Type type)
{
var xmlType = type.GetCustomAttribute<XmlTypeAttribute>();
if (xmlType != null && !string.IsNullOrEmpty(xmlType.Namespace))
return xmlType.Namespace;
return string.Empty;
}
}
顺便提一下,通过在内存中创建类的实例,对其进行序列化,然后将生成的XML与输入XML进行比较,可以轻松诊断出诸如此类的反序列化问题。 通常问题很明显。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.