这是我的XML文件
<?xml version="1.0" encoding="utf-8" ?>
<storage>
<Save Name ="Lifeline">
<Seconds>12</Seconds>
<Minutes>24</Minutes>
<Hours>9</Hours>
<Days>25</Days>
<Months>8</Months>
<Years>2010</Years>
<Health>90</Health>
<Mood>100</Mood>
</Save>
<Save Name ="Hellcode">
<Seconds>24</Seconds>
<Minutes>48</Minutes>
<Hours>18</Hours>
<Days>15</Days>
<Months>4</Months>
<Years>1995</Years>
<Health>50</Health>
<Mood>50</Mood>
</Save>
这是一个从XML获取数据并将其加载到应用程序中的代码。
System.IO.StreamReader sr = new System.IO.StreamReader(@"Saves.xml");
System.Xml.XmlTextReader xr = new System.Xml.XmlTextReader(sr);
System.Xml.XmlDocument save = new System.Xml.XmlDocument();
save.Load(xr);
XmlNodeList saveItems = save.SelectNodes("Storage/Save");
XmlNode seconds = saveItems.Item(0).SelectSingleNode("Seconds");
sec = Int32.Parse(seconds.InnerText);
XmlNode minutes = saveItems.Item(0).SelectSingleNode("Minutes");
min = Int32.Parse(minutes.InnerText);
XmlNode hours = saveItems.Item(0).SelectSingleNode("Hours");
hour = Int32.Parse(hours.InnerText);
XmlNode days = saveItems.Item(0).SelectSingleNode("Days");
day = Int32.Parse(days.InnerText);
XmlNode months = saveItems.Item(0).SelectSingleNode("Months");
month = Int32.Parse(months.InnerText);
XmlNode years = saveItems.Item(0).SelectSingleNode("Years");
year = Int32.Parse(years.InnerText);
XmlNode health_ = saveItems.Item(0).SelectSingleNode("Health");
health = Int32.Parse(health_.InnerText);
XmlNode mood_ = saveItems.Item(0).SelectSingleNode("Mood");
mood = Int32.Parse(mood_.InnerText);
问题是此代码从“生命线”节点加载数据。我想使用列表框,并能够选择从哪个节点加载数据。
我尝试从列表框项目内容中获取字符串,然后使用这样的行
XmlNodeList saveItems = save.SelectNodes(string.Format("storage/Save[@Name = '{0}']", name));
变量“name”是listboxe项目中的字符串。编译时,此代码提供异常。 有人知道如何通过属性选择并加载来自该XML的nedeed数据吗?
答案 0 :(得分:1)
如果你可以使用XElement:
XElement xml = XElement.Load(file);
XElement storage = xml.Element("storage");
XElement save = storage.Elements("Save").FirstOrDefault(e => ((string)e.Attribute("Name")) == nameWeWant);
if(null != save)
{
// do something with it
}
我个人喜欢具有转换为XElement和从XElement转换的属性的类,以隐藏主程序中的细节。 IE说Save类在构造函数中接受一个XElement节点,在全局内部保存它,并且属性读/写它。
示例类:
public class MyClass
{
XElement self;
public MyClass(XElement self)
{
this.self = self;
}
public string Name
{
get { return (string)(self.Attribute("Name") ?? "some default value/null"); }
set
{
XAttribute x = source.Attribute("Name");
if(null == x)
source.Add(new XAttribute("Name", value));
else
x.ReplaceWith(new XAttribute("Name", value));
}
}
}
然后您可以将搜索更改为:
XElement save = storage.Elements("Save")
.FirstOrDefault(e => new MyClass(e).Name == NameWeWant);
答案 1 :(得分:0)
select节点返回两个XmlNode对象。
XmlNodeList saveItems = save.SelectNodes("Storage/Save");
稍后在您的代码中,您似乎正在选择第一个并使用saveItems.Item(0)并从中获取值,在这种情况下,它将是具有Name =“LifeLine”的保存节点。因此,如果您要执行saveItems.Item(1)并选择节点及其值,那么您将获得另一组节点。
答案 2 :(得分:0)
由于数据不是那么多,我建议将所有信息加载到保存列表(构造函数),然后从那里绘制用户想要使用的数据......
至于不起作用的东西,我个人使用较低级别的方法来获取我的数据并且它不容易出错。重新设计它以适应您的问题:
int saves = 0;
List<Saves> saveGames = new List<Saves>();
saveGames.Add(new Saves());
while (textReader.Read())
{
if (textReader.NodeType == XmlNodeType.Element)
whatsNext = textReader.Name;
else if (textReader.NodeType == XmlNodeType.Text)
{
if (whatsNext == "name")
saveGames[saves].name = Convert.ToString(textReader.Value);
//else if statements for the rest of your attributes
else if (whatsNext == "Save")
{
saveGames.Add(new Saves());
saves++;
}
}
else if (textReader.NodeType == XmlNodeType.EndElement)
whatsNext = "";
}
基本上将xml文件中的所有内容都放入对象列表中并操纵该列表以填充列表框。而不是保存名称=“...”,将名称属性作为保存中的第一个属性。
代码标签恨我。为什么他们这么容易破解(._。)