【问题标题】:Creating class instances based on dynamic item lists基于动态项目列表创建类实例
【发布时间】:2016-06-17 09:26:06
【问题描述】:

我不确定是否可以通过为我正在运行的进程创建一个单独的类来使我的代码更简洁,但我这样做是因为我知道这样做。

我的主要目标是从通过 HtmlAgilityPack 收集的数据创建一个 JSON 文件。过去几天我一直在解决这个问题,但我设法找到了解决方法。我设法用检索到的信息创建了一个 JSON 文件,但它没有将信息分成对象数组中的单独对象。相反,它将所有数据聚集为 1 个对象。

发生这种情况是因为我从未在字符串列表中使用已解析的 html 数据创建对象。我不需要创建单独的列表并将它们组合起来,而是需要创建一个由解析的 html 数据组成的对象列表并将它们添加到列表中。

为了测试这个假设的方法,我创建了 3 个类实例并给它们赋值,以查看 JSON 文件是否创建了所需的对象数组。测试时,它会根据需要创建 JSON 对象数组。

JSON 创建:

[{"FavsGTS":"GT1","FavsGPICS":"GP1","FavsRNS":"RN1","FavsPIS":"PI1","FavsIsOns":"true"},
{"FavsGTS":"GT2","FavsGPICS":"GP2","FavsRNS":"RN2","FavsPIS":"PI2","FavsIsOns":"false"},
{"FavsGTS":"GT3","FavsGPICS":"GP3","FavsRNS":"RN3","FavsPIS":"PI3","FavsIsOns":"true"}]

现在我试图弄清楚如何根据收集的 html 数据动态创建实例。

我的想法是做类似的事情:

gamertagsFav = new List<string>(FavsGTS.Count);
            gamertagsFav.AddRange(FavsGTS);

            foreach(string gamertagfav in gamertagsFav)
            {
                //creates a class instance and adds the parsed data in the same order.   
            }

生成实例的示例如下:

gamerprofileFav gpfav1 = new gamerprofileFav()
            {
                FavsGTS = "gt1",
                FavsGPICS = "gpic1",
                FavsRNS = "rn1",
                FavsPIS = "pi1",
                FavsIsOns = "ison1"
            };

这是可能的,因为所有已解析的数据都按相同的顺序排列。

我的代码有点乱,但是很闲:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using Newtonsoft.Json;
using System.IO;

namespace Parser_Test_1._0
{
    public partial class Form1 : Form
    {
        public List<string> FavsGTS { get; private set; }
        public List<string> FavsGPICS { get; private set; }
        public List<string> FavsRNS { get; private set; }
        public List<string> FavsPIS { get; private set; }
        public List<string> FavsIsOns { get; private set; }
        public List<string> allPlayers { get; private set; }
        public List<string> gamertagsFav { get; private set; }

        public Form1()
        {
            InitializeComponent();
        }

        public class gamerprofileFav
        {
            public string FavsGTS { get; set; }
            public string FavsGPICS { get; set; }
            public string FavsRNS { get; set; }
            public string FavsPIS { get; set; }
            public string FavsIsOns { get; set; }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.Load(@"C:\Users\josec\Documents\Visual Studio 2015\Projects\THE XBOX PROJECT\Parser-Test-1.0\Parser-Test-1.0\bin\Debug\xbFrSourceCode.txt");

            string datacollected1 = doc.DocumentNode.SelectNodes("//*[@id=\"favoritesContent\"]/div[2]/div[2]/ul")[0].InnerHtml;
            string datacollected2 = doc.DocumentNode.SelectNodes("//*[@id=\"friendsContent\"]/div[2]/div[2]")[0].InnerHtml;
            label1.Text = datacollected1;
            label2.Text = datacollected2;

            //StreamWriter sw = new StreamWriter("datacollected1.txt");
            //sw.Write(datacollected1);
            //sw.Close();

            //Gamertags
            HtmlAgilityPack.HtmlDocument favs = new HtmlAgilityPack.HtmlDocument();
            favs.LoadHtml(datacollected1);

            FavsGTS = new List<string>();
            HtmlNodeCollection gts = favs.DocumentNode.SelectNodes("//li[@data-gamertag]");
            foreach (var gt in gts)
            {
                string datagamertag = gt.Attributes["data-gamertag"].Value;
                FavsGTS.Add(datagamertag);
            }

            listBox1.DataSource = FavsGTS;

            FavsGPICS = new List<string>();
            HtmlNodeCollection gpics = favs.DocumentNode.SelectNodes("//li/a[1]/img[1][@src]");
            foreach (var gpic in gpics)
            {
                string datagpic= gpic.Attributes["src"].Value;
                FavsGPICS.Add(datagpic);
            }

            listBox2.DataSource = FavsGPICS;

            FavsRNS = new List<string>();
            HtmlNodeCollection rns = favs.DocumentNode.SelectNodes("//li/div[2]/div[2]/div[1]/div[1]");
            foreach (var rn in rns)
            {
                string datarn = rn.InnerText;
                FavsRNS.Add(datarn);
            }

            listBox3.DataSource = FavsRNS;

            FavsPIS = new List<string>();
            HtmlNodeCollection pis = favs.DocumentNode.SelectNodes("//li/div[2]/div[2]/div[1]/div[2]");
            foreach (var pi in pis)
            {
                string datapi = pi.InnerText;
                FavsPIS.Add(datapi);
            }

            listBox4.DataSource = FavsPIS;

            FavsIsOns = new List<string>();
            HtmlNodeCollection isons = favs.DocumentNode.SelectNodes("//li[@data-isonline]");
            foreach (var ison in isons)
            {
                string dataison = ison.Attributes["data-isonline"].Value;
                FavsIsOns.Add(dataison);
            }

            listBox5.DataSource = FavsIsOns;
            //Test
            gamertagsFav = new List<string>(FavsGTS.Count);
            gamertagsFav.AddRange(FavsGTS);

            foreach(string gamertagfav in gamertagsFav)
            {

            }



            //Merge
            allPlayers = new List<string>(FavsGTS.Count + FavsGPICS.Count + FavsRNS.Count + FavsPIS.Count + FavsIsOns.Count);
            allPlayers.AddRange(FavsGTS);
            allPlayers.AddRange(FavsGPICS);
            allPlayers.AddRange(FavsRNS);
            allPlayers.AddRange(FavsPIS);
            allPlayers.AddRange(FavsIsOns);

            //GpsFav //+Start+
            gamerprofileFav gpfav1 = new gamerprofileFav()
            {
                FavsGTS = "GT1",
                FavsGPICS = "GP1",
                FavsRNS = "RN1",
                FavsPIS = "PI1",
                FavsIsOns = "true"
            };
            gamerprofileFav gpfav2 = new gamerprofileFav()
            {
                FavsGTS = "GT2",
                FavsGPICS = "GP2",
                FavsRNS = "RN2",
                FavsPIS = "PI2",
                FavsIsOns = "false"
            };
            gamerprofileFav gpfav3 = new gamerprofileFav()
            {
                FavsGTS = "GT3",
                FavsGPICS = "GP3",
                FavsRNS = "RN3",
                FavsPIS = "PI3",
                FavsIsOns = "true"
            };

            List<gamerprofileFav> gpfavs = new List<gamerprofileFav>();
            gpfavs.Add(gpfav1);
            gpfavs.Add(gpfav2);
            gpfavs.Add(gpfav3);
            //GgsFav //-END-

            listBox6.DataSource = allPlayers;
            listBox7.DataSource = gamertagsFav;

            //JSON Serialize
            //string data = JsonConvert.SerializeObject(gpfavs);
            //File.WriteAllText("data.json", data);
        }
        public class gpsFav
        {



        }

    }
}

这是运行时的 Form1:

5 个小列表中显示的数据是我希望按照它们出现的顺序分配给生成的实例的数据。这样我就可以根据这些生成的实例创建一个列表,我可以将其序列化为 JSON 文件。

【问题讨论】:

    标签: c# json visual-studio list visual-studio-2015


    【解决方案1】:

    为了避免做所有繁重的工作,已经有一个选项可以将 JSON 对象反序列化为您可以使用的 .NET 对象,例如您的一段代码;

    public class RootObject
    {
        public string FavsGTS { get; set; }
        public string FavsGPICS { get; set; }
        public string FavsRNS { get; set; }
        public string FavsPIS { get; set; }
        public string FavsIsOns { get; set; }
    }
    

    当你简单地反序列化它时;

    RootObject gamertag_sample = JsonConvert.DeserializeObject<RootObject>(jsonstr);
    

    当然,如果您将 RootObject 数组传递给它,您需要将 &lt;RootObject&gt; 替换为 &lt;RootObject[]&gt; 等等。

    据我了解,这是您寻求解决方案的唯一问题,还是我错过了什么?

    编辑: 使用动态对象,您可以创建任何您希望的值条目,但是在此之前您需要完成一系列任务。

    // this would contain your key,value for the generated instance.
    // {example_key, "value"} would result later in myObject.example_key (returning "value")
    var expandoObj = new ExpandoObject();
    var eoCollection = (ICollection<KeyValuePair<string, object>>)expandoObj;
    // add your key value pairs here
    eoCollection.Add(new KeyValuePair<string, object>("example", "example value"));
    
    dynamic myDynamicObject = expandoObj;
    // myDynamicObject.example will return "example value", and would result in json:
    //    "example":"example value"
    

    【讨论】:

    • 是的,你看错了。我现在不想反序列化任何 JSON 文件。我想连载一个。我设法弄清楚如何做到这一点,但要创建一个作为愿望,我需要先创建一个有组织的列表。我设法通过创建类实例来做到这一点。我试图弄清楚如何根据生成的列表动态创建类实例。
    • 那是我的错,对不起;您是否尝试过查看动态关键字选项?我只是有点麻烦地找到解决您所要求的解决方案,请原谅。
    • 我不确定“动态关键字选项”是什么,但我查看了动态对象和动态实例,但我还没有找到一种方法来根据解析的数据创建实例。目前,我试图弄清楚如何使用公共类gamerprofileFav上设置的所需信息为gamertagsfav中的每个gamertagfav创建一个实例。如果您知道任何可以帮助解决此问题的人,请分享/
    • 您可以像处理任何列表一样遍历解析的数据,并使用 .Add(key, value) 函数添加特定的数据条目。序列化动态对象将导致所有动态条目成为输出中的键:值。我编辑了主要帖子以澄清动态方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2011-11-02
    • 2020-05-11
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多