如何将XML数据解析为自定义C#类的属性? 安装程序
我的如何将XML数据解析为自定义C#类的属性? 安装程序,c#,xml,linq,C#,Xml,Linq,我的Main()函数中有这个 List<Token> tokens = new List<Token>(); string path = @"\(some directories)\tokens.xml"; XDocument doc = XDocument.Load(path); 我想我可以制作更多包含所有其他所需元素的列表,并执行相同的过程,但必须有更优雅的方式,对吗 编辑 我还试着从另一个问题开始。但是由于某种原因,当我试图从token向控制台写入内容时(比如to
Main()
函数中有这个
List<Token> tokens = new List<Token>();
string path = @"\(some directories)\tokens.xml";
XDocument doc = XDocument.Load(path);
我想我可以制作更多包含所有其他所需元素的列表,并执行相同的过程,但必须有更优雅的方式,对吗
编辑
我还试着从另一个问题开始。但是由于某种原因,当我试图从token
向控制台写入内容时(比如token.Name),它什么也没写
XmlSerializer serializer = new XmlSerializer(typeof(Token));
using (StringReader reader = new StringReader(path))
{
Token token = (Token)(serializer.Deserialize(reader));
}
可能只是一个不正确的实现。如果是这样的话,有人能使用我发布的内容并向我展示正确的实现吗?另外,我假设这将为我的两个列表属性提供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);
}
比我第一次想到的列表的数量要好得多。不像序列化那样简洁。然而,它满足了我的需要
谢谢你的帮助
编辑4
不确定这么多的编辑是允许的还是违反礼仪的。只是想为未来的读者做这个编辑
“答案”部分的内容确实解决了我的问题,但Dave在下面发布的XML序列化要好得多;它更灵活,更易于重用/修改。因此,选择对您的情况更有利的解决方案。查看以下帖子:
但是,使用下面的代码,将匿名类型转换为您的具体类。
这应该足以让你开始
XDocument xDoc = /* populate from somewhere */
XNamespace nsPlaceHolder = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
XNamespace ns = string.Empty;
var list1 = from list in xDoc.Descendants(ns + "cards")
from item in list.Elements(ns + "card")
/* where item.Element(ns + "card") != null */
select new
{
PicURL = item.Attribute("picURL").Value,
MyName = (item.Element(ns + "name") == null) ? string.Empty : item.Element(ns + "name").Value
};
foreach (var v in list1)
{
Console.WriteLine(v.ToString());
}
使用XML序列化,我能够将代码段反序列化为一些对象。我不太明白你的两个不同的列表变量,所以我把它修改成了一个列表
我不确定这是否正是您想要实现的,但我相信它会帮助您实现多个“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>
下面是输出的样子
使用Linq转换为Xml
string path = @"~/tokens.xml";
var doc = XDocument.Load(Server.MapPath(Url.Content(path)));
var cards = doc.Descendants("card")
.Select(x =>
new Token
{
Name = x.Element("name").Value,
SetURLs = x.Elements("set").Select(y => y.Attribute("picURL").Value)
.ToList(),
SetNames = x.Elements("set").Select(y => y.Value).ToList(),
Color = x.Element("color").Value,
PT = x.Element("pt").Value,
Text = x.Element("text").Value
}).ToList();
希望这能有所帮助。看看XML序列化有什么理由不只是使用XML序列化吗?@JuliánUrbano哦,是的,我也尝试过序列化。让我在那一部分补充一下。写一个高质量的问题做得很好:)哦………你的一些项目有多个“集合”元素。这是更棘手的。我需要四处看看。我想我花了10分钟的时间来编辑。这比我的解决方案好得多。我想我会继续在我的课程中使用(并学习)这个。非常感谢。我真的不应该把这个标记为答案,直到我真正让它工作起来。不要误解我的意思,这不适用于我的XML文件,因为我忘了在主要帖子中添加一个重要的细节。XML文件将
作为根元素。这将如何改变实施?这对我来说是一个相当愚蠢的错误。@KrimCard你能用更新的xml文件发布编辑吗?我可以帮助您调整代码以正确地反序列化。@KrimCard我修改了所有内容以解析您的文件。请注意,我真正需要做的就是添加另一个类来处理更高级别的项,并修改反序列化以使用该新类。不确定是否需要card_数据库的版本属性,但请将其放在那里。太好了。在发布第二条评论并研究代码之后,我确实做到了这一点:创建另一个类来处理更高的级别,并交换相关的类类型。它确实正确地反序列化了XML文件,但我不确定这是否是正确的(请原谅俚语,非janky)实现。只是想得到一些保证。谢谢你的帮助,非常感谢。
XDocument xDoc = /* populate from somewhere */
XNamespace nsPlaceHolder = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
XNamespace ns = string.Empty;
var list1 = from list in xDoc.Descendants(ns + "cards")
from item in list.Elements(ns + "card")
/* where item.Element(ns + "card") != null */
select new
{
PicURL = item.Attribute("picURL").Value,
MyName = (item.Element(ns + "name") == null) ? string.Empty : item.Element(ns + "name").Value
};
foreach (var v in list1)
{
Console.WriteLine(v.ToString());
}
<?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));
}
string path = @"~/tokens.xml";
var doc = XDocument.Load(Server.MapPath(Url.Content(path)));
var cards = doc.Descendants("card")
.Select(x =>
new Token
{
Name = x.Element("name").Value,
SetURLs = x.Elements("set").Select(y => y.Attribute("picURL").Value)
.ToList(),
SetNames = x.Elements("set").Select(y => y.Value).ToList(),
Color = x.Element("color").Value,
PT = x.Element("pt").Value,
Text = x.Element("text").Value
}).ToList();