gpt4 book ai didi

c# - 如何将 XML 数据解析为自定义 C# 类的属性?

转载 作者:数据小太阳 更新时间:2023-10-29 01:44:36 24 4
gpt4 key购买 nike

设置

我的 Main() 里有这个功能。

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

我的这个类有一些属性。

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 文件。这是一个片段。

<?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

如你所见,有很多 <card> <cards> 中的元素根元素。此外,每个 <card>可以有很多 <set>元素。我相应地开设了类(class)。

问题

我如何通过一个 <card>一次并为每个属性分配适当的值?

我尝试过的

我制作了一个包含所有 <name> 的列表每个元素 <card> .然后我将浏览此列表并为 Token 的新实例分配一个名称类(class)的Name属性(property)。然后填充我的 tokens列出每个新实例。

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);
}

我想我可以制作更多包含所有其他所需元素的列表并执行相同的过程,但必须有更优雅的方式,对吧?

编辑

我还尝试了另一个问题的序列化。但出于某种原因,当我试图从 token 写一些东西时到控制台(比如 token.Name),它没有写任何东西。

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

可能只是一个不正确的实现。如果是这样,有人可以使用我发布的内容并向我展示正确的实现吗?此外,我假设这将为我的两个 List 提供 1 个或多个值。属性,对吗?

编辑

感谢您的帮助。

编辑2

一个答案

在对序列化进行了一些不成功的摆弄和更多搜索之后,我实现了一个可行的实现。

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);
}

Lists的数字好多了我首先想到的是。不像序列化那样简洁。但是,它满足了我的需要。

感谢您的帮助。

编辑4

不确定这么多的编辑是允许还是违反礼节。只是想为 future 的读者做这个编辑。

“答案”部分下的内容确实解决了我的问题,但 Dave 在下面发布的 XML 序列化要好得多;它更灵活,更容易重用/修改。因此,请选择对您的情况有更多好处的解决方案。

最佳答案

使用 XML 序列化,我能够将您的代码段反序列化为一些对象。我不太了解您的 2 个不同的列表变量,所以我将其修改为 1 个列表。

我不确定这是否正是您想要实现的,但我相信它应该可以帮助您对多个“set”元素进行 xml 反序列化。

我使用与您相同的代码段创建了一个名为 tokens.xml 的文件,并进行了编辑以匹配您的新布局。

<?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>

我创建了几个类

[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; }
}

正文如下(我知道这很丑,但我走得很快所以请改进)

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));
}

下面是输出的样子。

Watch output

关于c# - 如何将 XML 数据解析为自定义 C# 类的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16153196/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com