如何将XML数据解析为一个自定义的C#类的属性? [英] How to parse XML data into the properties of a custom C# class?
问题描述
我有这在我的的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屋!