如何在C#中反序列化XML时修复空列表?

huangapple go评论65阅读模式
英文:

How do I fix an empty List when deserializing XML in C#?

问题

尝试反序列化包含名为Controller的列表的Networks对象,该列表有3个条目。Controller内部还有另一个名为network的列表。Controller列表始终为空。我已经查看了StackOverflow上的几篇帖子,但没有帮助。任何帮助将不胜感激。

我已经定义了以下类:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace TestXML
{
    [Serializable()]
    [XmlRoot("Networks")]
    public class Networks
    {
        [XmlArray(ElementName = "Controller")]
        [XmlArrayItem("NetworkController")]
        public List<NetworkController> Controller { get; set; }

        [XmlAttribute("computer")]
        public string computer { get; set; }

        [XmlAttribute("GlobalFPPProxy")]
        public string GlobalFPPProxy { get; set; }

        [XmlAttribute("GlobalForceLocalIP")]
        public string GlobalForceLocalIP { get; set; }
    }

    [XmlType("NetworkController")]
    public class NetworkController
    {
        [XmlAttribute(AttributeName = "Id")]
        public string Id { get; set; }

        [XmlAttribute(AttributeName = "Name")]
        public string Name { get; set; }

        [XmlArray(ElementName = "network")]
        [XmlArrayItem("NetworkControllerNetwork")]
        public List<NetworkControllerNetwork> network { get; set; }
    }

    [XmlType("NetworkControllerNetwork")]
    public class NetworkControllerNetwork
    {
        [XmlAttribute(AttributeName = "ComPort")]
        public string ComPort { get; set; }

        [XmlAttribute("BaudRate")]
        public int BaudRate { get; set; }

        [XmlAttribute("NetworkType")]
        public string NetworkType { get; set; }

        [XmlAttribute("MaxChannels")]
        public int MaxChannels { get; set; }
    }
}

我使用以下代码反序列化Networks XML:

private readonly string xml = @"<Networks computer=""DESKTOP-281OHFP"" GlobalFPPProxy=""GlobalFPPProxy"" GlobalForceLocalIP=""GlobalForceLocalIP"">
    <Controller Id=""100"" Name=""Falcon F4V3 1"">
        <network ComPort=""192.168.1.254"" BaudRate=""100"" NetworkType=""E131"" MaxChannels=""512""/>
        <network ComPort=""192.168.1.254"" BaudRate=""101"" NetworkType=""E131"" MaxChannels=""512""/>
        <!-- 其它 network 条目 -->
    </Controller>
    <!-- 其它 Controller 条目 -->
</Networks>";

private void GenerateXML_Click(object sender, EventArgs e)
{
    Networks result = new();
    string inputString = xml; 

    XmlDocument doc = new ();
    doc.LoadXml(inputString);

    XmlSerializer serializer = new (typeof(Networks));
    StringReader rdr = new(doc.InnerXml);
    if (rdr is not null)
    {
        if (serializer is not null)
            result = serializer.Deserialize(rdr) as Networks;
        rdr.Close();
    }
}

请注意,我已经将XML字符串从HTML编码中解码为正常XML字符串。

英文:

Trying to deserialize Networks object which contains a List called Controller which has 3 entries.
Within Controller is another List called network.
The Controller List is always empty.
I have reviewed several posts in StackOverflow but nothing has helped.
Any help will be greatly appreciated.

I have defined the following Class

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace TestXML
{

    [Serializable()]
    [XmlRoot(&quot;Networks&quot;)]
    public class Networks
    {
        [XmlArray(ElementName = &quot;Controller&quot;)]
        [XmlArrayItem(&quot;NetworkController&quot;)]
        public List&lt;NetworkController&gt; Controller { get; set; }

        [XmlAttribute(&quot;computer&quot;)]
        public string computer { get; set; }

        [XmlAttribute(&quot;GlobalFPPProxy&quot;)]
        public string GlobalFPPProxy { get; set; }

        [XmlAttribute(&quot;GlobalForceLocalIP&quot;)]
        public string GlobalForceLocalIP { get; set; }

    }

    [XmlType(&quot;NetworkController&quot;)]
    public class NetworkController
    {
        //[XmlElement(ElementName = &quot;Id&quot;)]
        [XmlAttribute (AttributeName =&quot;Id&quot;)]
        public string Id { get; set; }

        //[XmlElement(ElementName = &quot;Name&quot;)]
        [XmlAttribute(AttributeName = &quot;Name&quot;)]
        public string Name { get; set; }

        [XmlArray(ElementName = &quot;network&quot;)]
        [XmlArrayItem(&quot;NetworkControllerNetwork&quot;)]
        public List&lt;NetworkControllerNetwork&gt; network { get; set; }

    }


    [XmlType(&quot;NetworkControllerNetwork&quot;)]
    public class NetworkControllerNetwork
    {
        [XmlAttribute(AttributeName = &quot;ComPort&quot;)]
        public string ComPort { get; set; }

        [XmlAttribute(&quot;BaudRate&quot;)]
        public int BaudRate { get; set; }

        [XmlAttribute(&quot;NetworkType&quot;)]
        public string NetworkType { get; set; }

        [XmlAttribute(&quot;MaxChannels&quot;)]
        public int MaxChannels { get; set; }

    }

}

And I use the following code to deserialize the Networks XML

 private readonly string xml = @&quot;&lt;Networks computer=&quot;&quot;DESKTOP-281OHFP&quot;&quot; GlobalFPPProxy=&quot;&quot;GlobalFPPProxy&quot;&quot; GlobalForceLocalIP=&quot;&quot;GlobalForceLocalIP&quot;&quot;&gt;
	&lt;Controller Id=&quot;&quot;100&quot;&quot; Name=&quot;&quot;Falcon F4V3 1&quot;&quot;&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;100&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;101&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;102&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;103&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;104&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
		&lt;network ComPort=&quot;&quot;192.168.1.254&quot;&quot; BaudRate=&quot;&quot;105&quot;&quot; NetworkType=&quot;&quot;E131&quot;&quot; MaxChannels=&quot;&quot;512&quot;&quot;/&gt;
	&lt;/Controller&gt;
	&lt;Controller Id=&quot;&quot;1&quot;&quot; Name=&quot;&quot;Serial_&quot;&quot;&gt;
		&lt;network ComPort=&quot;&quot;COM4&quot;&quot; BaudRate=&quot;&quot;250000&quot;&quot; NetworkType=&quot;&quot;DMX&quot;&quot; MaxChannels=&quot;&quot;1&quot;&quot;/&gt;
	&lt;/Controller&gt;
	&lt;Controller Id=&quot;&quot;2&quot;&quot; Name=&quot;&quot;Null_&quot;&quot;&gt;
		&lt;network NetworkType=&quot;&quot;NULL&quot;&quot; MaxChannels=&quot;&quot;1&quot;&quot;/&gt;
	&lt;/Controller&gt;
&lt;/Networks&gt;
 &quot;;

        private void GenerateXML_Click(object sender, EventArgs e)
        {
            Networks result = new();
            string inputString = xml; 

            XmlDocument doc = new ();
            doc.LoadXml(inputString);

            XmlSerializer serializer = new (typeof(Networks));
            StringReader rdr = new(doc.InnerXml);
            if (rdr is not null)
            {
                if (serializer is not null)
                    result = serializer.Deserialize(rdr) as Networks;
					//richTextBox1.Text = result.Controller.ToString();
                rdr.Close();
                
            }
            
        }

答案1

得分: 1

这部分
`[XmlArray(ElementName = &quot;Controller&quot;)] 
[XmlArrayItem(&quot;NetworkController&quot;)]`
表示在`Controller`标签内有一个`NetworkController`项目列表,就像这样:

    &lt;Controller ....&gt;
      &lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
      &lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
      &lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
      .....
    &lt;/Controller&gt;

这在你的XML中不存在,你应该使用 `[XmlElement(ElementName = &quot;Controller&quot;)]`。

对于`[XmlArray(ElementName = &quot;network&quot;)]
        [XmlArrayItem(&quot;NetworkControllerNetwork&quot;)]`

使用 `[XmlElement(ElementName = &quot;network&quot;)]`

并从`NetworkController`类中移除`[XmlType(&quot;NetworkController&quot;)]`,从`NetworkControllerNetwork`类中移除`[XmlType(&quot;NetworkControllerNetwork&quot;)]`

**这是最终结果:**

    [Serializable()]
    [XmlRoot(&quot;Networks&quot;)]
    public class Networks
    {
        [XmlElement(ElementName = &quot;Controller&quot;)]
        public List&lt;NetworkController&gt; Controller { get; set; }

        [XmlAttribute(&quot;computer&quot;)]
        public string computer { get; set; }

        [XmlAttribute(&quot;GlobalFPPProxy&quot;)]
        public string GlobalFPPProxy { get; set; }

        [XmlAttribute(&quot;GlobalForceLocalIP&quot;)]
        public string GlobalForceLocalIP { get; set; }

    }

    public class NetworkController
    {
        //[XmlElement(ElementName = &quot;Id&quot;)]
        [XmlAttribute(AttributeName = &quot;Id&quot;)]
        public string Id { get; set; }

        //[XmlElement(ElementName = &quot;Name&quot;)]
        [XmlAttribute(AttributeName = &quot;Name&quot;)]
        public string Name { get; set; }

        [XmlElement(ElementName = &quot;network&quot;)]
        public List&lt;NetworkControllerNetwork&gt; network { get; set; }

    }


    public class NetworkControllerNetwork
    {
        [XmlAttribute(AttributeName = &quot;ComPort&quot;)]
        public string ComPort { get; set; }

        [XmlAttribute(&quot;BaudRate&quot;)]
        public int BaudRate { get; set; }

        [XmlAttribute(&quot;NetworkType&quot;)]
        public string NetworkType { get; set; }

        [XmlAttribute(&quot;MaxChannels&quot;)]
        public int MaxChannels { get; set; }

    }
英文:

This part
[XmlArray(ElementName = &quot;Controller&quot;)]
[XmlArrayItem(&quot;NetworkController&quot;)]

means there is NetworkController list of items inside Controller tag, like this

&lt;Controller ....&gt;
&lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
&lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
&lt;NetworkController ....&gt;....&lt;/NetworkController&gt;
.....
&lt;/Controller&gt;

Which is not in your XML, You have to use [XmlElement(ElementName = &quot;Controller&quot;)].

The same thing with [XmlArray(ElementName = &quot;network&quot;)]
[XmlArrayItem(&quot;NetworkControllerNetwork&quot;)]

Use [XmlElement(ElementName = &quot;network&quot;)]

And remove [XmlType(&quot;NetworkController&quot;)] from NetworkController class and [XmlType(&quot;NetworkControllerNetwork&quot;)] from NetworkControllerNetwork class

This is the final result:

[Serializable()]
[XmlRoot(&quot;Networks&quot;)]
public class Networks
{
[XmlElement(ElementName = &quot;Controller&quot;)]
public List&lt;NetworkController&gt; Controller { get; set; }
[XmlAttribute(&quot;computer&quot;)]
public string computer { get; set; }
[XmlAttribute(&quot;GlobalFPPProxy&quot;)]
public string GlobalFPPProxy { get; set; }
[XmlAttribute(&quot;GlobalForceLocalIP&quot;)]
public string GlobalForceLocalIP { get; set; }
}
public class NetworkController
{
//[XmlElement(ElementName = &quot;Id&quot;)]
[XmlAttribute(AttributeName = &quot;Id&quot;)]
public string Id { get; set; }
//[XmlElement(ElementName = &quot;Name&quot;)]
[XmlAttribute(AttributeName = &quot;Name&quot;)]
public string Name { get; set; }
[XmlElement(ElementName = &quot;network&quot;)]
public List&lt;NetworkControllerNetwork&gt; network { get; set; }
}
public class NetworkControllerNetwork
{
[XmlAttribute(AttributeName = &quot;ComPort&quot;)]
public string ComPort { get; set; }
[XmlAttribute(&quot;BaudRate&quot;)]
public int BaudRate { get; set; }
[XmlAttribute(&quot;NetworkType&quot;)]
public string NetworkType { get; set; }
[XmlAttribute(&quot;MaxChannels&quot;)]
public int MaxChannels { get; set; }
}

huangapple
  • 本文由 发表于 2023年6月2日 06:54:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76386181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定