Чтобы ответить на ваш ответ на другой дубликат вопроса:
Я пытался извлечь строку из содержимого элемента списка, а затем использовать такую строку
XmlNodeList saveItems = save.SelectNodes (string.Format ("storage / Save [@Name = '{0}']", name));
переменная "name" является строкой из элемента listboxe. Во время компиляции этот код дает исключение. Кто-нибудь знает, как выбрать по атрибуту и загрузить необходимые данные из этого XML?
Я подозреваю, что вы не получаете правильные значения от вашего ListBox
. Все зависит от того, как вы его заселили. Если вы просто использовали конструктор для заполнения ваших ListBox
именами string
, вам следует использовать свойство SelectedItem
, чтобы получить выбранное имя. Если, с другой стороны, вы заполнили свой ListBox, установив DataSource
, установите для свойства ValueMember
соответствующее имя свойства и используйте SelectedValue
для получить значение.
Хотя вы никогда не упоминали, что это было за исключение, это всего лишь догадка.
Ваша проблема изначально заключалась в том, что вы использовали неправильный XPath. Поскольку это было неправильно, все последующие обращения к первому результату вернули null
, что привело к NullReferenceException
. Ответ BrokenGlass охватывает использование правильного XPath.
Если XML-файл, который вы нам показываете, действительно соответствует содержимому файла и вы получаете соответствующее значение name
, то все должно работать здесь.
В целом, код можно упростить гораздо больше. Я использую здесь LINQ, чтобы упростить работу с недопустимыми именами. Вы должны найти, что это рабочий код.
var xmlStr = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<storage>
<Save Name =""Lifeline"">
<!-- etc... (trimmed off for brevity) -->
</Save>
<Save Name =""Hellcode"">
<!-- etc... -->
</Save>
</storage>
";
var doc = new XmlDocument();
doc.LoadXml(xmlStr);
var name = "Hellcode";
var settings =
doc.SelectNodes(String.Format("/storage/Save[@Name='{0}']", name))
.Cast<XmlElement>()
.Select(e => new
{
Seconds = Convert.ToInt32(e["Seconds"].InnerText),
Minutes = Convert.ToInt32(e["Minutes"].InnerText),
Hours = Convert.ToInt32(e["Hours"].InnerText),
Days = Convert.ToInt32(e["Days"].InnerText),
Months = Convert.ToInt32(e["Months"].InnerText),
Years = Convert.ToInt32(e["Years"].InnerText),
Health = Convert.ToInt32(e["Health"].InnerText),
Mood = Convert.ToInt32(e["Mood"].InnerText),
})
.SingleOrDefault();
Trace.WriteLine("settings: " + settings);
Я бы предпочел здесь LINQ to XML, так как он намного чище. Это также должно работать с xmlStr
, указанным выше.
var doc = XDocument.Parse(xmlStr);
var name = "Hellcode";
var settings =
doc.Element("storage")
.Elements("Save")
.Where(e => e.Attribute("Name").Value == name)
// or if using XPath, the above could be replaced with:
// doc.XPathSelectElements(String.Format("/storage/Save[@Name='{0}']", name))
.Select(e => new
{
Seconds = (int)e.Element("Seconds"),
Minutes = (int)e.Element("Minutes"),
Hours = (int)e.Element("Hours"),
Days = (int)e.Element("Days"),
Months = (int)e.Element("Months"),
Years = (int)e.Element("Years"),
Health = (int)e.Element("Health"),
Mood = (int)e.Element("Mood"),
})
.SingleOrDefault();
Trace.WriteLine("settings: " + settings);