反序列化xml,包括命名空间

时间:2015-08-11 07:13:00

标签: c# xml deserialization xml-deserialization

我正在尝试反序列化某些XML,但我无法使命名空间/ xsi:type="Model"正常工作。如果xsi:type="Model"被排除在XML之外,它就可以运行,但它必须存在。如果我将命名空间从模型中删除,我会收到错误,如果我重命名它,我会得到一个空列表。

XML

<Vehicles xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Vehicle xsi:type="Model">
        <Id>238614402</Id>
    </Vehicle>
    <Vehicle xsi:type="Model">
        <Id>238614805</Id>
    </Vehicle>
</Vehicles>

模型

[XmlRootAttribute("Vehicles")]
public class Vehicles
{
    public Vehicles() 
    {
        Vehicle = new List<Vehicle>();
    }

    [XmlElement(ElementName = "Vehicle", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public List<Vehicle> Vehicle { get; set; }
}


public class Vehicle
{
    [XmlElement("Id")]
    public int Id { get; set; }

}

反序列化

XmlSerializer serializer = new XmlSerializer(typeof(Vehicles));
string carXML = "<Vehicles xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Vehicle  xsi:type=\"Model\"> <Id>238614402</Id> </Vehicle><Vehicle  xsi:type=\"Model\"> <Id>238614805</Id> </Vehicle></Vehicles>";

var cars = (Vehicles)serializer.Deserialize(new StringReader(carXML));

上面的示例返回一个空列表,因为命名空间是错误的,据我所知 - 如何让它返回实际列表?

修改 我无法控制XML,我从其他提供商那里得到了这些,因此我必须相应地更改其余的代码。

1 个答案:

答案 0 :(得分:6)

请试试这个:

public partial class Vehicles
{
    [XmlElement("Vehicle")]
    public Vehicle[] Vehicle { get; set; }
}

[XmlInclude(typeof(Model))]
public partial class Vehicle
{
    public uint Id { get; set; }
}

public class Model : Vehicle { }

注意输入vehicle

var xs = new XmlSerializer(typeof(Vehicles));
Vehicles vehicles;

using (var fs = new FileStream("file.xml", FileMode.Open))
{
    vehicles = (Vehicles)xs.Deserialize(fs);
}

foreach (var vehicle in vehicles.Vehicle)
{
    Console.WriteLine(vehicle.GetType()); // Model
    Console.WriteLine(vehicle.Id);
}

无需指定命名空间。序列化属性xsi时,系统会自动添加实际类型Model

xs.Serialize(Console.Out, vehicles);