c# - 反序列化 XML,其中每个对象都有一个对象列表

标签 c# xml

我正在开发一个 WP7 应用程序,它可以获取和更新网络服务器上的数据。如果有任何更新需要响应,我会得到一个需要处理的错误列表,以及每个错误的可能选择列表。我遇到的问题是为每个对象分配适当的选择列表。截至目前,我得到了一个错误列表,以及所有错误的所有可能选择的另一个列表。我希望错误对象只包含它的选项列表,这样我就可以处理它。

下面是一个示例响应:

<?xml version="1.0" encoding="utf-8"?>
<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <response_error_dialogs>
        <error_dialog_list>
            <error_dialog_choice>
                <error_dialog_id>1301</error_dialog_id>
                <error_dialog_message>You have changed the phone number.  Select which phone number to make the primary contact number.</error_dialog_message>
                <error_dialog_title>Phone Number Changed</error_dialog_title>
                <error_dialog_is_set>false</error_dialog_is_set>
                <error_dialog_choice_option_list>
                    <error_dialog_choice_option>
                        <error_dialog_choice_option_id>1</error_dialog_choice_option_id>
                        <error_dialog_choice_option_title>Home</error_dialog_choice_option_title>
                    </error_dialog_choice_option>
                    <error_dialog_choice_option>
                        <error_dialog_choice_option_id>2</error_dialog_choice_option_id>
                        <error_dialog_choice_option_title>Mobile</error_dialog_choice_option_title>
                    </error_dialog_choice_option>
                    <error_dialog_choice_option>
                        <error_dialog_choice_option_id>3</error_dialog_choice_option_id>
                        <error_dialog_choice_option_title>Work</error_dialog_choice_option_title>
                    </error_dialog_choice_option>
                </error_dialog_choice_option_list>
            </error_dialog_choice>
            <error_dialog_choice>
                <error_dialog_id>1303</error_dialog_id>
                <error_dialog_message>You have changed the account email address.  Would you like this to be the new default email?</error_dialog_message>
                <error_dialog_title>Email Address Changed</error_dialog_title>
                <error_dialog_is_set>false</error_dialog_is_set>
                <error_dialog_choice_option_list>
                    <error_dialog_choice_option>
                        <error_dialog_choice_option_id>1</error_dialog_choice_option_id>
                        <error_dialog_choice_option_title>No</error_dialog_choice_option_title>
                    </error_dialog_choice_option>
                    <error_dialog_choice_option>
                        <error_dialog_choice_option_id>2</error_dialog_choice_option_id>
                        <error_dialog_choice_option_title>Yes</error_dialog_choice_option_title>
                    </error_dialog_choice_option>
                </error_dialog_choice_option_list>
            </error_dialog_choice>
        </error_dialog_list>
    </response_error_dialogs>
</response>

这里是使用的类:

public class ErrorDialog
{
    XElement self;

    public ErrorDialog() { }

    public ErrorDialog(XElement errorDialog)
    {
        self = errorDialog;
    }

    public int errorDialogId
    {
        get { return (int)(self.Element("error_dialog_id")); }
    }
    public string errorDialogMessage
    {
        get { return (string)(self.Element("error_dialog_message")); }
    }
    public string errorDialogTitle
    {
        get { return (string)(self.Element("error_dialog_title")); }
    }
    public bool errorDialogIsSet
    {
        get { return (bool)(self.Element("error_dialog_is_set")); }
    }
    public List<ErrorDialogChoice> errorDialogChoice
    {
        get { return (List<ErrorDialogChoice>)(errorDialogChoice); }
    }
    public int errorDialogSelectedOption
    {
        get { return (int)(self.Element("error_dialog_selected_option")); }
    }
}

class ErrorDialogChoice
{
    XElement self;

    public ErrorDialogChoice() { }

    public ErrorDialogChoice(XElement errorDialogChoice)
    {
        self = errorDialogChoice;
    }

    public int errorDialogChoiceOptionId
    {
        get { return (int)(self.Element("error_dialog_choice_option_id")); }
    }
    public string errorDialogChoiceOptionTitle
    {
        get { return (string)(self.Element("error_dialog_choice_option_title")); }
    }
}

下面是我解析它的方式:

XElement response = XElement.Parse(data);  

ErrorDialog[] dialogs = response
    .Element("response_error_dialogs")
    .Element("error_dialog_list")
    .Elements("error_dialog_choice")
    .Select(e => new ErrorDialog(e))
    .ToArray();

ErrorDialogChoice[] edChoices = response
    .Element("response_error_dialogs")
    .Element("error_dialog_list")
    .Element("error_dialog_choice")
    .Element("error_dialog_choice_option_list")
    .Elements("error_dialog_choice_option")
    .Select(e => new ErrorDialogChoice(e))
    .ToArray();

因此对于这个例子,第一个 error_dialog_choice 对象将有一个 List 包含 3 个 error_dialog_choice_option 对象,第二个有两个 error_dialog_choice_option 对象,以及任何可能返回的对象。任何帮助表示赞赏。谢谢。

最佳答案

您可以使用 XML 序列化来更轻松地实现这一点:

var reader = new StringReader(xmlString);
var ser = new XmlSerializer(typeof(Response));
var result = (Response) ser.Deserialize(reader);

使用这些类定义。

[XmlType("response")]
public class Response
{
    [XmlElement("response_error_dialogs")]
    public ErrorDialog ErrorDialog;
}

[XmlType("response_error_dialogs")]
public class ErrorDialog
{
    [XmlArray("error_dialog_list")]
    public List<ChoiceErrorDialog> ChoiceList;
}

[XmlType("error_dialog_choice")]
public class ChoiceErrorDialog
{
    [XmlElement("error_dialog_id")]
    public int Id;

    [XmlElement("error_dialog_message")]
    public string Message;

    [XmlElement("error_dialog_title")]
    public string Title;

    [XmlElement("error_dialog_is_set")]
    public bool IsSet;

    [XmlArray("error_dialog_choice_option_list")]
    public List<Option> OptionList;
}

[XmlType("error_dialog_choice_option")]
public class Option
{
    [XmlElement("error_dialog_choice_option_id")]
    public int Id;

    [XmlElement("error_dialog_choice_option_title")]
    public string Title;
}

我猜可能会有更多类型的错误对话框,并且 <error_dialog_choice>只是可能的类型之一。在这种情况下,您可以使用子类化,并使用 XmlArrayItem 列出子类。属性。


您还可以生成类定义 xsd.exesvcutil.exe , 来自.xsd.wsdl文件。 xsd.exe甚至可以从样本 .xml 中推断模式文件。

xsd.exe /?
svcutil.exe /?

关于c# - 反序列化 XML,其中每个对象都有一个对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11712666/

相关文章:

php - 在 PHP 中读取的批量 XML 文件

Java 将 NodeList 转换为 String 以检查 xml 注释

c# - 如何从类中调用变量

java - 如何制作只能通过接口(interface)访问的类?

c# - 在单个 ListView 中显示多个模型

c# - SelectSingleNode 和命名空间 - 找不到节点(使用命名空间 mgr)

python - 如何让 Beautifulsoup 不添加 <html> 或 <?xml ?>

c# - 如何在 C# 中使用 `switch` 仅基于类型参数有条件地分支?

c# - 在Windows中访问其他一些特定于应用程序的卷

.net - 将 C#3 代码表示为 XML 中的抽象语法树