4

我试图反序列化一个 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));

而且我里面确实有几个子数组对象,比如里面的宝马。但它不是序列化汽车。有人可以在这里指出我的错误吗?

4

4 回答 4

3

尝试使用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; }
}
于 2012-05-29T19:26:23.950 回答
2

尝试将预期对象序列化为 xml 并进行比较。(Serialize 方法甚至比 Deserialize 更容易。)这可能会突出显示错误放置或错误命名的属性。

于 2012-05-29T19:26:53.187 回答
0

I have several suggestions and a nice working example for you. First of all, I suggest a different class structure that takes advantage of class hierarchy.

Here is what you need:

  • CarList - A wrapper class for managing your list of Cars
  • Car - A class that provides all of the basic Car properties and methods
  • BMW - A specific type of Car class. It inherits the parent Car class and provides additional properties and methods.

When you want to add more Car types, you would create another class and have it also inherit from the Car class.

On to the code...

Here is your CarList class. Notice that the List of Car objects has multiple XmlElement declarations on it. This is so that the serialization/de-serialization knows how to handle the different Car types. As you add more types, you will have to add a line here to describe the type.

Also, notice the static Save and Load methods that handle the serialization/de-serialization.

[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();
  }
}

Next, here is your Car class...

public class Car
{
  // put properties and methods common to all car types here
  [XmlAttribute("Id")]
  public long Id { get; set; }
}

And finally, your specific Car types...

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

Load your CarList like this:

CarList carList = CarList.Load(@"C:\cars.xml");

Make some changes, then Save your CarList like this:

CarList.Save(carList, @"C:\cars.xml");

And here is what the XML looks like:

<?xml version="1.0" encoding="utf-8"?>
<CarList Name="My Car List">
  <BWM Id="1234" NavVendor="Alpine" />
  <Acura Id="2345" SunroofTint="true" />
</CarList>

Hope that helps get you started in the right direction!

于 2012-05-29T20:34:16.933 回答
0

我想我发现了问题所在。我没有包括我在 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 或模式来生成我的理想对象。

于 2012-05-30T15:14:05.647 回答