【问题标题】:How to deserialize nested structure with XmlSerializer如何使用 XmlSerializer 反序列化嵌套结构
【发布时间】:2014-05-12 19:17:33
【问题描述】:

我有一个字符串形式的 xml。假设是字符串。

<?xml version='1.0' encoding='utf-8'?>
<parameter>
    <name>max_amount</name>
    <label>Max Amount</label>
    <unit>Millions</unit>
    <component>
        <type>Combo</type>
        <attributes>
            <type>Integer</type>
            <displayed>4</displayed>
            <selected>0</selected>
            <items>
                <item>5</item>
                <item>10</item>
                <item>20</item>
                <item>50</item>
            </items>
        </attributes>
    </component>
</parameter>

我已经成功反序列化并得到了它的对象:

[XmlRoot(ElementName = "parameter")]
public class Parameter
{
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("label")]
    public string Label { get; set; }
    [XmlElement("unit")]
    public string Unit { get; set; }
    [XmlElement("component")]
    public Component Component { get; set; }
}

[XmlRoot(ElementName = "component")]
public class Component
{
    [XmlElement("type")]
    public string Type { get; set; }
    [XmlElement("attributes")]
    public Attributes Attributes { get; set; }
}

[XmlRoot(ElementName = "attributes")]
public class Attributes
{
    [XmlElement("type")]
    public string Type { get; set; }
    [XmlElement("displayed")]
    public string Displayed { get; set; }
    [XmlElement("selected")]
    public string Selected { get; set; }
    [XmlArray("items")]
    [XmlArrayItem("item", typeof(string))]
    public List<string> Items { get; set; }

}

我的主类是这样的,我访问 xml 的所有元素:

XmlSerializer deserializer = new XmlSerializer(typeof(Parameter));
XmlReader reader = XmlReader.Create(new StringReader(xmlstring));
Parameter parameter = (Parameter)deserializer.Deserialize(reader);
foreach (var item in parameter.Component.Attributes.Items)
{
    Debug.WriteLine(item);
}
Debug.WriteLine(parameter.Component.Type);
Debug.WriteLine(parameter.Name);
Debug.WriteLine(parameter.Label);
Debug.WriteLine(parameter.Unit);

直到这里一切都很好,但是如果 xml 是嵌套的,如果我有这样的 xml:

<parameter>
....
....
....
</parameter>
<parameter>
....
....
....
</parameter>

详细:如果我的xml字符串是这样的:

<?xml version='1.0' encoding='utf-8'?>
<parameter>
    <name>max_amount</name>
    <label>Max Amount</label>
    <unit>Millions</unit>
    <component>
        <type>Combo</type>
        <attributes>
            <type>Integer</type>
            <displayed>4</displayed>
            <selected>0</selected>
            <items>
                <item>5</item>
                <item>10</item>
                <item>20</item>
                <item>50</item>
            </items>
        </attributes>
    </component>
</parameter>
<parameter>
    <name>max_amount_again</name>
    <label>Max Amount_again</label>
    <unit>Millions_again</unit>
    <component>
        <type>Combo</type>
        <attributes>
            <type>Integer</type>
            <displayed>41</displayed>
            <selected>01</selected>
            <items>
                <item>50</item>
                <item>100</item>
                <item>200</item>
                <item>500</item>
            </items>
        </attributes>
    </component>
</parameter>

这次我将如何获取元素?因为这里的 参数 是“父”类,当我们反序列化它时这样做 " Parameter parameter = (Parameter)deserializer.Deserialize(reader);" 我们将得到一个对象parameter 以及如何访问第二个 &lt;parameter&gt;..&lt;/parameter&gt;&lt;parameter&gt;..How to get the data here..&lt;/parameter&gt;

【问题讨论】:

  • 所以你想得到一个参数列表? List&lt;Parameter&gt;?
  • 首先,第二个不是有效的 XML 文档,所以我猜你不会反序列化类似的东西。
  • 您有 2 个根 XML 元素 - 这是不允许的。将 2 个 &lt;parameter&gt; 放入一个 &lt;parameters&gt; 以便能够解析它。
  • 读取异常信息。
  • @OhaxNuv 谢谢,是的,我想要两个 List 的对象

标签: c# .net xml deserialization xml-deserialization


【解决方案1】:

如果您的 xml 文档看起来像这样(这是一个有效的 xml 文档):

<?xml version='1.0' encoding='utf-8' ?>
<parameters>
  <parameter>
    <name>max_amount</name>
    <label>Max Amount</label>
    <unit>Millions</unit>
    <component>
      <type>Combo</type>
      <attributes>
        <type>Integer</type>
        <displayed>4</displayed>
        <selected>0</selected>
        <items>
          <item>5</item>
          <item>10</item>
          <item>20</item>
          <item>50</item>
        </items>
      </attributes>
    </component >
  </parameter>
  <parameter>
    <name>max_amount_again</name>
    <label>Max Amount_again</label>
    <unit>Millions_again</unit>
    <component>
      <type>Combo</type>
      <attributes>
        <type>Integer</type>
        <displayed>41</displayed>
        <selected>01</selected>
        <items>
          <item>50</item>
          <item>100</item>
          <item>200</item>
          <item>500</item>
        </items>
      </attributes>
    </component >
  </parameter>
</parameters>

您将需要另一个类来存储所有元素&lt;parameter&gt;...&lt;/parameter&gt;

public class Parameters
{
    [XmlElement("parameter")]
    public List<Parameter> parameterList = new List<Parameter>();        
} 

并将该文档反序列化到该类中。

XmlSerializer deserializer = new XmlSerializer(typeof(Parameters));
using (TextReader reader = new StreamReader(@"C:\path\to\your\xml"))
{
    object obj = deserializer.Deserialize(reader);
    Parameters deserialized = (Parameters)obj;
}

要访问那些 parameter 元素,您可以简单地使用 foreach 循环,例如:

Parameters p = new Parameters();

foreach (Parameter parameter in p.parameterList)
{
    Console.WriteLine(parameter.Name);
}

【讨论】:

  • 能否请您告诉我,我将如何访问两个参数类的元素,我的意思是“Debug.WriteLine(parameter.Name);”其中包含“max_amount”和“Debug.WriteLine(parameter.Name);”其中包含“max_amount_gain”?
  • 现在。它会同时显示 max_amount 和 max_amount_again 吗?调试中?
  • @user234839 是的,它将显示所有 .. 元素中的所有名称。编辑:这会打印到控制台到stdout
  • 没有“Valid xml”也是可能的,而您可能应该声明 xml 文档,因为它仍然可以被视为 xml。
猜你喜欢
  • 2014-07-23
  • 2023-03-26
  • 2022-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多