繁体   English   中英

如何反序列化xml字符串

[英]How to deserialize an xml string

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

我确实有像宝马里面的几个子阵列对象。 不,它不是序列化汽车。 有人可以在这里指出我的错误吗?

尝试使用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并进行比较。 (Serialize方法比Deserialize更容易。)这可能会突出显示错误放置或错误命名的属性。

我有几个建议和一个很好的工作实例。 首先,我建议使用不同的类结构来利用类层次结构。

这是你需要的:

  • CarList - 用于管理汽车列表的包装类
  • Car - 提供所有基本Car属性和方法的类
  • 宝马 - 特定类型的汽车级。 它继承了父Car类并提供了其他属性和方法。

当您想要添加更多Car类型时,您将创建另一个类并让它继承Car类。

关于代码......

这是你的CarList课程。 请注意,Car对象列表上有多个XmlElement声明。 这样序列化/反序列化就知道如何处理不同的Car类型。 在添加更多类型时,您必须在此处添加一行来描述类型。

另外,请注意处理序列化/反序列化的静态Save和Load方法。

[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 = 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或架构来生成我认为理想的opbject。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM