Разбор XML файла с использованием С#?
Я новичок в XML и С#; Я пытаюсь найти способ эффективно разобрать данный XML файл для получения соответствующих числовых значений, основываясь на значении "proj_title" = heat_run или любых других возможных значениях. Например, вычисление продолжительности конкретного тестового прогона (proj_end val-proj_start val).
ex.xml:
<proj ID="2">
<proj_title>heat_run</proj_title>
<proj_start>100</proj_start>
<proj_end>200</proj_end>
</proj>
...
Мы не можем выполнить поиск по идентификатору proj, так как это значение не фиксируется из тестового прогона в тестовый прогон. Вышеупомянутый файл огромен: ~ 8mb, а там ~ 2000 тегов с именем proj_title. есть эффективный способ сначала найти все имена тегов w/proj_title= "heat_run", затем получить начальное и конечное значение proj для этого конкретного proj_title с помощью С#??
Здесь мой текущий код С#:
public class parser
{
public static void Main()
{
XmlDocument xmlDoc= new XmlDocument();
xmlDoc.Load("ex.xml");
//~2000 tags w/ proj_title
//any more efficient way to just look for proj_title="heat_run" specifically?
XmlNodeList heat_run_nodes=xmlDoc.GetElementsByTagName("proj_title");
}
}
Ответы
Ответ 1
Вы можете использовать XPath для поиска всех узлов, которые соответствуют, например:
XmlNodeList matches = xmlDoc.SelectNodes("proj[proj_title='heat_run']")
matches
будет содержать все узлы proj
, которые соответствуют критерию. Подробнее о XPath: http://www.w3schools.com/xsl/xpath_syntax.asp
Документация MSDN на SelectNodes
Ответ 2
8MB действительно не очень велик по современным стандартам. Лично я бы использовал LINQ для XML:
XDocument doc = XDocument.Load("ex.xml");
var projects = doc.Descendants("proj_title")
.Where(x => (string) x == "heat_run")
.Select(x => x.Parent) // Just for simplicity
.Select(x => new {
Start = (int) x.Element("proj_start"),
End = (int) x.Element("proj_end")
});
foreach (var project in projects)
{
Console.WriteLine("Start: {0}; End: {1}", project.Start, project.End);
}
(Очевидно, приспособите это к вашим собственным требованиям - это не совсем понятно, что вам нужно делать на основе вопроса.)
Альтернативный запрос:
var projects = doc.Descendants("proj")
.Where(x => (string) x.Element("proj_title") == "heat_run")
.Select(x => new {
Start = (int) x.Element("proj_start"),
End = (int) x.Element("proj_end")
});
Ответ 3
Используйте XDocument и используйте LINQ api.
http://msdn.microsoft.com/en-us/library/bb387098.aspx
Если производительность не такая, как вы ожидаете, попробовав ее, вы должны искать парсер для сакса.
Парсер Sax не будет загружать весь документ в память и попытаться применить выражение xpath во всем в памяти. Он работает больше в режиме, основанном на событиях, и в некоторых случаях это может быть намного быстрее и не использует столько памяти.
Есть, вероятно, саксофоризаторы для .NET там, они не использовали их для .NET, но я сделал для С++.