将难以形成的XML反序列化为C#对象

时间:2010-01-28 03:51:05

标签: c# xml serialization

我的XML由第三方Web服务以下列形式返回:

<object>
    <list name="subscriptions">
        <object>
            <string name="id">something</string> 
            <string name="title">something else</string> 
            <list name="categories" /> 
            <number name="timestamp">1252707770116</number> 
        </object>
        ...more 'object'...
    </list>
</object>

我在尝试将此数据反序列化为对象时遇到了很多问题。我无法使用xsd.exe生成模式,所以我手动生成了以下类来尝试拟合这些数据:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlAttribute()]
    public string id;
    [XmlAttribute()]
    public string title;
    [XmlAttribute()]
    public string[] categories;
    [XmlAttribute()]
    public string timestamp;
}

我正在尝试使用以下代码对其进行反序列化:

XmlSerializer s = new XmlSerializer(typeof(ListOfSubscriptions));
StreamReader r = new StreamReader("out.xml");
ListOfSubscriptions listSubscribe = (ListOfSubscriptions)s.Deserialize(r);
r.Close();

但是,当它完成时,listSubscribe有一个成员,其所有字段都为空。

我应该如何创建用于反序列化的模板?

由于

更新 - 2010/01/28

感谢大家的评论我已将课程修改为以下内容:

[XmlRoot("object")]
public class ListOfSubscriptions
{
    [XmlElement("list")]
    public SubscriptionList[] items;
}
[XmlRoot("list")]
public class SubscriptionList
{
    [XmlElement("object")]
    public Subscription[] items;
}

[XmlRoot("object")]
public class Subscription
{
    [XmlElement("string")]
    public string id;
    [XmlElement("string")]
    public string title;
    [XmlElement("list")]
    public string[] categories;
    [XmlElement("number")]
    public string timestamp;
}

如果我在Subscription中注释掉[XmlElement(...)]行并运行,我会认为listSubscribe有一个SubscriptionList项具有正确的订阅数量,但是,所有订阅的元素为空。

如果我取消注释XmlElement行,则会收到反映订阅的错误。我想它会变得混乱,因为有多个具有相同名称的元素。

如何将属性名称绑定到类成员?

4 个答案:

答案 0 :(得分:4)

你走在正确的轨道上。但是,您只定义了两个类。实际上有三个类要定义:

  1. 单个根对象,XML名称为“object”。这将只有一个成员:
  2. 对象列表(XML名称为“list”)。这将有一个成员,数组:
  3. 订阅,XML名称为“object”。
  4. 另一个问题是您将Subscription字段定义为属性。它们不是属性,它们是元素。

答案 1 :(得分:2)

你永远不会得到像这样的XML:

<string name="id">something</string>  

这只是由不懂XML的人创建的。等价物:

<id>something</id>

很容易反序列化。


我能想到的唯一方法就是通过在类上实现IXmlSerializable接口来反序列化。

答案 2 :(得分:0)

您需要更改XmlArryXMLArrayItem

Here就是一个例子。看起来应该是这样的:

[XmlArray("FullNames")]
[XmlArrayItem("Name")]
public string[] Names{get;set;}

会给你

<FullNames>
    <Name>Michael Jackson</Name>
    <Name>Paris Hilton</Name>
</FullNames>

答案 3 :(得分:0)

我相信您可以使用XSD.exe .Net framework实用程序生成一个可用于XML文档内存表示的类。