将XML文件中的数据排序为数据集

时间:2017-03-16 17:29:25

标签: c# winforms dataset linq-to-xml

所以我有以下xml文件,我的Windows窗体来自网站。

<WebserviceResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="">
<data xmlns="">
<ArrayOfMatches>
    <Match>
    <TimeSlot>17:00:00</TimeSlot>
    <Game_Id>18</Game_Id>
    <ArrayOfTeams>
        <Team>
            <Team_id>14</Team_id>
            <Team_Name>New Zealand</Team_Name>
            <TeamPlayers>
                <Player>
                    <PlayerId>10</PlayerId>
                    <PlayerName>Trent</PlayerName>
                    <PlayerSurname>Boult</PlayerSurname>
                </Player>
                    <Player>...</Player>
                    <Player>...</Player>
                    <Player>...</Player>
            </TeamPlayers>
        </Team>
        <Team>
            <Team_id>16</Team_id>
            <Team_Name>west indies</Team_Name>
            <TeamPlayers>...</TeamPlayers>
        </Team>
    </ArrayOfTeams>
    </Match>
</ArrayOfMatches>
</data>

这只是整个事情的片段,这里的想法是两个团队将面对彼此,分配一个Game_Id

目前我的想法是将Game_Id Team_IdTeam_Name加载到一行中的数据集中,每个Game_Id(有xml文件中的多个游戏)。团队名称最终将以Team1 V Team2的形式出现在组合框中;然后,当选择一个时,Player个元素将被加载到两个单独的列表框中。

我目前能够做的是用TimeSlot&amp;填充不同的数据集。 Game_Id,使用TeamPlayers的xml文件中的所有DS.ReadXML(xmlRead),但不是我想要的方式,并将Game_Id放在一个组合框中:

XmlElement root = xdoc.DocumentElement;

XmlNodeList nodeList = xdoc.GetElementsByTagName("Match");
foreach (XmlNode xn in nodeList)
{
     cb_matches.Items.Add(xn.InnerText);
}

这些都有效但不是我想做的事。

对此事的任何帮助都将不胜感激,我觉得我已尽可能多地提供信息。

EDITED

<Date> </Date>每个网络服务只出现一次,当天有多个<Game_Id>。它用于确保使用正确的XML文件。

EDITED

<data xmlns="">
    <ArrayOfMatches>
        <Match>...</Match>
        <Match>...</Match>
    </ArrayOfMatches>
</data>

EDITED

所以我仍然比这更难挣扎。

+-----+-------+---------+------------+---------+-----------+
|Time |Game_Id|Team_A_Id|Team_A_Name |Team_B_Id|Team_B_Name|
|17:00|18     |14       |South Africa|16       |West Indies|
|19:00|19     |18       |New Zealand |12       |England    |

这是我想要的结构DataTable

现在我一直在玩xml-linq等,但我似乎不能像那样说出来。

        XDocument xdoc = XDocument.Load(@"c:/matchdata.xml");
        IEnumerable<XElement> games = xdoc.Descendants("ArrayOfMatches");

        var matches = games
            .Select(x => new Games()
            {
                GameID = x.Element("Game_Id").Value,
                TeamAID = x.Element("Team_Id").Value,
                TeamAName = x.Element("Team_Name").Value,
                TeamBID = x.Element("Team_Id").Value,
                TeamBName = x.Element("Team_Name").Value
            });

        dataGridView1.DataSource = xdoc;

这会编译,但不显示gridview中的任何数据,也不会显示任何错误。

2 个答案:

答案 0 :(得分:1)

您可以将整个XML反序列化为对象并轻松使用它 (我从你的xml片段中删除了第一行,而匹配是一个条目,因为如果有多个匹配,则不清楚Date会去哪里,

<data>
    <ArrayOfMatches>
        <Date>2017-04-04</Date>
        <Match>
            <TimeSlot>17:00:00</TimeSlot>
            <Game_Id>18</Game_Id>
            <ArrayOfTeams>
                <Team>
                    <Team_id>14</Team_id>
                    <Team_Name>New Zealand</Team_Name>
                    <TeamPlayers>
                        <Player>
                            <PlayerId>10</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player>
                          <Player>
                            <PlayerId>11</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player>
                        <Player>
                            <PlayerId>12</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player> 
                    </TeamPlayers>
                </Team>
                <Team>
                    <Team_id>15</Team_id>
                    <Team_Name>New Zealand</Team_Name>
                    <TeamPlayers>
                        <Player>
                            <PlayerId>10</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player>
                          <Player>
                            <PlayerId>11</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player>
                        <Player>
                            <PlayerId>12</PlayerId>
                            <PlayerName>Trent</PlayerName>
                            <PlayerSurname>Boult</PlayerSurname>
                        </Player> 
                    </TeamPlayers>
                </Team>
            </ArrayOfTeams>
        </Match>
    </ArrayOfMatches>
</data>

但你应该明白这一点)

现在您可以使用result了。 通过抓取诸如game_id,球队阵列,球员等属性。

    public class data
    {
        public DateTime Date { get; set; }
        public Match[] ArrayOfMatches { get; set; }

    }

    public class ArrayOfMatches
    {

        public Match[] Match { get; set; }

    }

    public class Match
    {
        public String TimeSlot { get; set; }
        public int Game_Id { get; set; }
        public Team[] ArrayOfTeams { get; set; }
    }    

    public class Team { 
        public int Team_id { get; set; }
        public string Team_Name { get; set; }
        public Player[] TeamPlayers { get; set; }
    }   

    public class Player
    {
        public int PlayerId { get; set; }
        public string PlayerName { get; set; }
        public string PlayerSurname { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (FileStream fileStream = new FileStream(@"C:\temp\input.xml", FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(data));
                data result = (data)serializer.Deserialize(fileStream);
            }

        }
    }

答案 1 :(得分:0)

data wanted;
    format collect $1000.;
    retain collect;
    set begin; 
    if id = bill then collect = catx("/",collect,product);
    if id ~= bill then collect = catx("-",collect,product);
run;    

这样一来,var dt = new DataTable(); dt.Columns.Add(new DataColumn("TimeSlot", typeof(string))); dt.Columns.Add(new DataColumn("GameID", typeof(string))); dt.Columns.Add(new DataColumn("TeamAID", typeof(string))); dt.Columns.Add(new DataColumn("TeamAName", typeof(string))); dt.Columns.Add(new DataColumn("TeamBID", typeof(string))); dt.Columns.Add(new DataColumn("TeamBName", typeof(string))); XDocument xdoc = XDocument.Load(@"c:/matchdata.xml"); var games = from i in xdoc.Descendants("Match") select new //creates a few new anonymous types to store values to dump into the datatable { TimeSlot = (string)i.Element("TimeSlot"), GameID = (string)i.Element("Game_Id"), TeamAID = (string)i.Element("ArrayOfTeams").Element("Team").Element("Team_id"), TeamAName = (string)i.Element("ArrayOfTeams").Element("Team").Element("Team_Name"), TeamBID = (string)i.Element("ArrayOfTeams").Elements("Team").Skip(1).First().Element("Team_id"), //skips a node to collect info for the next team. TeamBName = (string)i.Element("ArrayOfTeams").Elements("Team").Skip(1).First().Element("Team_Name") //skips a node to collect info for the next team. }; foreach (var item in games) { dt.Rows.Add(item.TimeSlot, item.GameID, item.TeamAID, item.TeamAName, item.TeamBID, item.TeamBName); //adds a new row of data into the datatable for every <Match> </Match> } 可以成为dt的来源,您可以看到结果。这可能不是最好的方法,但至少我已经学到了一些东西,对更好/更有效的评论将被研究。