如何反序列化 xml 字符串
本文关键字:字符串 xml 反序列化 | 更新日期: 2023-09-27 18:35:43
我试图反序列化一个 xml 字符串,但我没有反序列化对象。
我的 xml 字符串看起来像
<Cars>
<Car>
<Id>123445</Id>
<BMW>
<Id>78945</Id>
</BMW>
</Car>
</Cars>
[Serializable()]
[XmlRoot("Cars")]
public class Cars
{
[XmlArrayItem("Car",typeof(Car))]
public Car[] Car { get; set; }
}
[Serializable()]
public class Car
{
[XmlElement("Id")]
public long Id { get; set; }
[XmlArrayItem("BMW",typeof(BMW))]
public BMW[] BMW { get; set; }
}
[Serializable()]
public class BMW
{
[XmlElement("Id")]
public long Id { get; set; }
}
这是我正在尝试的代码:
string str = "xml string like above";
XmlSerializer ser = new XmlSerializer(typeof(Cars));
var wrapper = (Cars) ser.Deserialize(new StringReader(str));
而且我里面确实有几个子数组对象,比如里面的宝马。BUt 它不是序列化汽车。有人可以在这里指出我的错误吗?
尝试使用 XmlElement
而不是 XmlArrayItem
,因为这些项目没有封装标签:
[Serializable()]
[XmlRoot("Cars")]
public class Cars
{
[XmlElement("Car",typeof(Car))]
public Car[] Car { get; set; }
}
[Serializable()]
public class Car
{
[XmlElement("Id")]
public long Id { get; set; }
[XmlElement("BMW",typeof(BMW))]
public BMW[] BMW { get; set; }
}
尝试将
预期的对象序列化为 xml 并进行比较。 (序列化方法甚至比反序列化方法更容易。 这可能会突出显示放置错误或命名错误的属性。
我有几个建议和一个很好的工作示例给你。首先,我建议使用一种不同的类结构来利用类层次结构。
以下是您需要的:
- CarList - 用于管理汽车列表的包装类 Car
- - 提供所有基本 Car 属性和方法的类
- 宝马 - 一种特定类型的汽车类别。它继承父 Car 类并提供其他属性和方法。
当您想要添加更多 Car 类型时,您将创建另一个类,并让它也继承自 Car 类。
关于代码...
下面是您的 CarList 类。 请注意,Car 对象列表上有多个 XmlElement 声明。这样序列化/反序列化就知道如何处理不同的 Car 类型。添加更多类型时,必须在此处添加一行来描述类型。
此外,请注意处理序列化/反序列化的静态保存和加载方法。
[XmlRoot("CarList")]
public class CarList
{
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlElement("Cars")]
[XmlElement("BWM", typeof(BMW))]
[XmlElement("Acura", typeof(Acura))]
//[XmlArrayItem("Honda", typeof(Honda))]
public List<Car> Cars { get; set; }
public static CarList Load(string xmlFile)
{
CarList carList = new CarList();
XmlSerializer s = new XmlSerializer(typeof(CarList));
TextReader r = new StreamReader(xmlFile);
carList = (CarList)s.Deserialize(r);
r.Close();
return carList;
}
public static void Save(CarList carList, string fullFilePath)
{
XmlSerializer s = new XmlSerializer(typeof(CarList));
TextWriter w = new StreamWriter(fullFilePath);
// use empty namespace to remove namespace declaration
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
s.Serialize(w, carList, ns);
w.Close();
}
}
接下来,这是您的汽车类...
public class Car
{
// put properties and methods common to all car types here
[XmlAttribute("Id")]
public long Id { get; set; }
}
最后,您的特定车型...
public class BMW : Car
{
// put properties and methods specific to this type here
[XmlAttribute("NavVendor")]
public string navigationSystemVendor { get; set; }
}
public class Acura : Car
{
// put properties and methods specific to this type here
[XmlAttribute("SunroofTint")]
public bool sunroofTint { get; set; }
}
像这样加载您的车单:
CarList carList = CarList.Load(@"C:'cars.xml");
进行一些更改,然后像这样保存您的 CarList:
CarList.Save(carList, @"C:'cars.xml");
下面是 XML 的外观:
<?xml version="1.0" encoding="utf-8"?>
<CarList Name="My Car List">
<BWM Id="1234" NavVendor="Alpine" />
<Acura Id="2345" SunroofTint="true" />
</CarList>
希望这能帮助您朝着正确的方向开始!
我想
我发现了问题所在。我没有包括我在 xml 中恢复的所有属性。如果缺少任何属性,反序列化将不起作用。我还像这样添加了这一行:
[XmlArray(Form = XmlSchemaForm.Unqualified),
XmlArrayItem("BMW", typeof(BMW), Form = XmlSchemaForm.Unqualified, IsNullable = false)]
public BMW[] BMWs { get; set; }
如果你的 xml 有这样的东西:
<Cars>
<Car>
<Id>123445</Id>
<BMWs>
<BMW>
<Id>78945</Id>
<BMW>
</BMWs>
</Car>
</Cars>
然后它奏效了。我没有任何 XSD 或模式来生成我的 opbjects,这将是理想的。