如何将XML数据解析为一个自定义的C#类的属性? [英] How to parse XML data into the properties of a custom C# class?

查看:92
本文介绍了如何将XML数据解析为一个自定义的C#类的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这在我的的Main()功能。

List<Token> tokens = new List<Token>();
string path = @"\(some directories)\tokens.xml";
XDocument doc = XDocument.Load(path);



我有这个类的一些属性。

I have this class with a few properties.

public partial class Token
{
    public Token()
    {
        SetURLs = new List<string>();
        SetNames = new List<string>();
    }

    public string Name { get; set; }
    public List<string> SetURLs { get; set; }
    public List<string> SetNames { get; set; }
    public string Color { get; set; }
    public string PT { get; set; }
    public string Text { get; set; }
}



我有这样的XML文件。这里是一个片段

I have this XML file. Here is a snippet.

<?xml version="1.0" encoding="UTF-8"?> //EDIT3
<card_database version="2">            //EDIT3
    <cards>
        .
        .
        .
        <card>
            <name>Griffin</name>
            <set picURL="http://magiccards.info/extras/token/duel-decks-ajani-vs-nicol-bolas/griffin.jpg" picURLHq="" picURLSt="">DDH</set>
            <color>w</color>
            <manacost></manacost>
            <type>Token</type>
            <pt>2/2</pt>
            <tablerow>0</tablerow>
            <text>Flying</text>
            <token>1</token>
        </card>
        <card>
            <name>Rat</name>
            <set picURL="http://magiccards.info/extras/token/shadowmoor/rat.jpg" picURLHq="" picURLSt="">SHM</set>
            <set picURL="http://magiccards.info/extras/token/gatecrash/rat.jpg" picURLHq="" picURLSt="">GTC</set>
            <color>b</color>
            <manacost></manacost>
            <type>Token</type>
            <pt>1/1</pt>
            <tablerow>0</tablerow>
            <text></text>
            <token>1</token>
        </card>
        .
        .
        .
    </cards>
</card_database> //EDIT3



正如你所看到的,有许多<卡> <元素;卡和GT; 根元素。此外,每个<卡> 可以有很多的<集> 元素。我作出相应的类。

As you can see, there are many <card> elements in the <cards> root element. Further, each <card> can have many <set> elements. I made the class accordingly.

我该如何去通过一个< ;卡> 在一个时间并分配相应的值每个属性。

How do I go through one <card> at a time and assign the appropriate values to each property?

我做了一个包含所有℃的列表;名称>每个元素<卡> 。然后我会去通过这个列表,并分配一个名称令牌类的名称属性的新实例。然后填充我标记每一个新实例列表

I made a list that contains all of the <name> elements of each <card>. I would then go through this list and assign a name to a new instance of the Token class's Name property. Then populate my tokens list with each new instance.

List<string> names = new List<string>();
names = doc.Descendants("card").Elements("name").Select(r => r.Value).ToList();
int amount = doc.Descendants("card").Count();

for(int i = 0; i < amount; i++)
{
    Token token = new Token();

    token.Name = name[i];

    .
    .
    .

    tokens.Add(token);
}



我想那时我能有这样的包含所有其他所需的元素,做更多的列表同样的过程,但必须有一个更优雅的方式,对吧?

I guess I could then make more lists that contain every other desired element and do the same process, but there has to be a more elegant way, right?

修改

我也试过从系列化另一个问题。但由于某些原因,当我试着写在东西令牌控制台(比如token.Name),它并没有写任何东西。

I also tried serialization from another question. But for some reason, when I tried to write something from token to the console (say token.Name), it didn't write anything.

XmlSerializer serializer = new XmlSerializer(typeof(Token));
using (StringReader reader = new StringReader(path))
{
    Token token = (Token)(serializer.Deserialize(reader));
}



也许只是一个不正确的执行。如果是这样的话,可能会有人用什么我张贴,并告诉我正确实施?另外,我认为这会给1个或多个值,以我的两个列表属性吧?

修改

感谢您的帮助。

EDIT2

与序列化和一些更多的搜索一些不成功的摆弄之后,我做了工作的落实。

After some unsuccessful fiddling with serialization and some more searching, I made an implementation that works.

foreach (var card in doc.Descendants("card"))
{
    Token token = new Token();

    token.Name = card.Element("name").Value.ToString();
    foreach (var set in card.Elements("set"))
    {
        token.SetURLs.Add(set.Attribute("picURL").Value.ToString());
        token.SetNames.Add(set.Value.ToString());
    }
    token.Color = card.Element("color").Value.ToString();
    token.PT = card.Element("pt").Value.ToString();
    token.Text = card.Element("text").Value.ToString();

    tokens.Add(token);
}



远远高于列表的数目更好我第一次的想法。还不如简洁的序列化可能已经。但是,它确实是我所需要的。

Much better than the number of Lists I first had in mind. Not as succinct as the serialization might have been. However, it does what I need.

感谢您的帮助。

EDIT4

不知道这许多编辑被允许或反对的礼仪。 。只是想让此编辑为未来的读者

Not sure if this many edits are allowed or against etiquette. Just wanted to make this edit for future readers.

在回答部分下的东西不解决我的问题,但由Dave贴在下面的XML序列化要好得多;它更灵活,更易于重复使用/修改。所以,选择那些适合您的情况更多的利益的解决方案。

The stuff under the "An Answer" section does solve my problem but the XML Serialization posted below by Dave is much better; it is more flexible and easier to reuse/modify. So, pick the solution that has more benefits for your situation.

推荐答案

使用XML序列化,我能够反序列化片段到一些对象。我真的不明白你的2个不同的变量列表,所以我修改了它到1名单。

Using XML Serialization I was able to deserialize your snippet into some objects. I don't really understand your 2 different list variables so i modified it into 1 list.

我不知道这是否是你想拉过什么,但我相信它会帮助你多的设置元素的XML序列化。

I am not sure if this is exactly what you are trying to pull off, but i believe it should help you with your xml deserialization of multiple "set" elements.

我创建了一个文件,你同样片断命名tokens.xml,编辑以符合您的新的布局

I created a file with your same snippet named tokens.xml, edited to match your new layout.

<?xml version="1.0" encoding="UTF-8"?> 
<card_database version="2">
  <cards>
    <card>
      <name>Griffin</name>
      <set picURL="http://magiccards.info/extras/token/duel-decks-ajani-vs-nicol-bolas/griffin.jpg" picURLHq="" picURLSt="">DDH</set>
      <color>w</color>
      <manacost></manacost>
      <type>Token</type>
      <pt>2/2</pt>
      <tablerow>0</tablerow>
      <text>Flying</text>
      <token>1</token>
    </card>
    <card>
      <name>Rat</name>
      <set picURL="http://magiccards.info/extras/token/shadowmoor/rat.jpg" picURLHq="" picURLSt="">SHM</set>
      <set picURL="http://magiccards.info/extras/token/gatecrash/rat.jpg" picURLHq="" picURLSt="">GTC</set>
      <color>b</color>
      <manacost></manacost>
      <type>Token</type>
      <pt>1/1</pt>
      <tablerow>0</tablerow>
      <text></text>
      <token>1</token>
    </card>
  </cards>
</card_database>



我创建了几类

I created a few classes

[XmlRoot(ElementName = "card_database")]
public class CardsDatabase
{
    public CardsDatabase()
    {

    }
    [XmlElement(ElementName = "cards", Form = XmlSchemaForm.Unqualified)]
    public CardsList Cards { get; set; }

    [XmlAttribute(AttributeName = "version", Form = XmlSchemaForm.Unqualified)]
    public string Version { get; set; }
}

[XmlRoot(ElementName = "cards")]
public class CardsList
{
    public CardsList()
    {
        Cards = new List<Card>();
    }
    [XmlElement(ElementName = "card", Form = XmlSchemaForm.Unqualified)]
    public List<Card> Cards { get; set; } 
}

[XmlRoot(ElementName = "card")]
public class Card
{
    public Card()
    {
        SetURLs = new List<SetItem>();

    }

    [XmlElement(ElementName = "name", Form = XmlSchemaForm.Unqualified)]
    public string Name { get; set; }

    [XmlElement(ElementName = "set", Form = XmlSchemaForm.Unqualified)]
    public List<SetItem> SetURLs { get; set; }

    [XmlElement(ElementName = "color", Form = XmlSchemaForm.Unqualified)]
    public string Color { get; set; }

    [XmlElement(ElementName = "pt", Form = XmlSchemaForm.Unqualified)]
    public string PT { get; set; }

    [XmlElement(ElementName = "text", Form = XmlSchemaForm.Unqualified)]
    public string Text { get; set; }

}

[XmlRoot(ElementName = "set")]
public class SetItem
{
    public SetItem()
    {

    }

    [XmlAttribute(AttributeName = "picURL", Form = XmlSchemaForm.Unqualified)]
    public string PicURL { get; set; }

    [XmlAttribute(AttributeName = "picURLHq", Form = XmlSchemaForm.Unqualified)]
    public string PicURLHq { get; set; }

    [XmlAttribute(AttributeName = "picURLSt", Form = XmlSchemaForm.Unqualified)]
    public string PicURLSt { get; set; }

    [XmlText]
    public string Value { get; set; }
}



主体如下(我知道这是丑陋的,但我得很快,所以请提高)

The main body is as follows (I know this is ugly, but i was going fast so please improve)

CardsDatabase cards = new CardsDatabase();
string path = @"tokens.xml";
XmlDocument doc = new XmlDocument();
doc.Load(path);

XmlSerializer serializer = new XmlSerializer(typeof(CardsDatabase));
using (StringReader reader = new StringReader(doc.InnerXml))
{
    cards = (CardsDatabase)(serializer.Deserialize(reader));
}



下面是输出是什么样子。

The following is what the output looked like.

这篇关于如何将XML数据解析为一个自定义的C#类的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆