2012-04-10 10 views
1

Ich habe ein großes XML-Dokument und verwende C#, um den Inhalt abzufragen. Ich habe etwas ähnliches wie die folgenden:Filtern von XmlNodeList mit zusätzlicher XPath-Abfrage?

var bookA = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=123]"); 
var bookB = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=456]"); 
var bookC = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=789]"); 

Wie Sie sehen können, die Filter auf „yearPublished“ in jeder Abfrage wiederholt wird und, bitte korrigieren Sie mich, wenn ich falsch, die gesamte Liste der Bücher analysiert wird wiederholt . Wäre es effizienter zu sein, etwas zu haben, wie folgt aus:

var newBooks = xmlDoc.SelectNodes("/books/book[yearPublished=2012]"); 
var bookA = newBooks.SelectSingleNode("book[id=123]"); 
var bookB = newBooks.SelectSingleNode("book[id=456]"); 
var bookC = newBooks.SelectSingleNode("book[id=789]"); 

Unter der Annahme, mein Dokument groß ist (sagen wir es, die Daten über mehrere tausend Bücher enthält), bin ich richtig, dass es effizienter wäre, die Daten zu filtern basierend auf dem ersten Kriterium und wählen Sie dann den gewünschten XmlNode aus der gefilterten Liste?

Zweitens versuchte ich, meine Annahme zu bestätigen, aber ich habe Probleme. Ich erhalte eine Fehlermeldung über SelectSingleNode:

‚System.Xml.XmlNodeList‘ keine Definition für ‚SelectSingleNode‘ enthält und keine Erweiterungsmethode ‚SelectSingleNode‘ ein erstes Argument vom Typ ‚System.Xml zu akzeptieren. XmlNodeList‘könnte gefunden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis?)

ich habe einen Verweis auf System.Xml und‚using System.Xml‘auch. Vermisse ich etwas anderes?

+0

Die XML ist "bereits geparst", wenn "xmlDoc" verwendet wird. Nur die XPath-Abfrage muss [re] ausgewertet werden. Ja, mehrere Male bedeutet "mehr Arbeit", aber es bedeutet nicht "praktisch langsamer" und es könnte genauso schnell sein - oder schneller! - als Iteration, wegen der ID-Klausel. Der einzige Weg, etwas zu wissen, ist Benchmarking. –

+0

Persönlich bevorzuge ich XDocument/[XElement] (http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement_members (v = vs90) .aspx) und Freunde, da es XPath unterstützt über Erweiterungsmethoden. Ist es schneller?Ich weiß es nicht oder interessiert mich, weil mir die Schnittstelle besser gefällt, es sieht sauberer aus und ich habe keine solchen Leistungsüberlegungen :-) –

Antwort

2

Die SelectNodes Methode gibt einen XmlNodeList Typ zurück. Die Methode SelectSingleNode gehört zur Klasse XmlNode.

var bookA = newBooks.Where(x => x.Attributes["id"].Value == 123); 
var bookB = newBooks.Where(x => x.Attributes["id"].Value == 456); 
var bookC = newBooks.Where(x => x.Attributes["id"].Value == 789); 
+0

Obwohl dies "langsamer" sein könnte (fsvo, in einigen degenerierten Fällen) als die drei separaten Abfragen weil der Selektor nicht die 'ID' im DOM nutzen kann. –

1
var newBooks = xmlDoc.SelectNodes("/books/book[yearPublished=2012]"); 

Dies wird wieder ein XmlNodeList Objekt:

Sie können Ihre Bücher wie diese erhalten. Dieses Objekt enthält keine Methode namens SelectSingleNode, weshalb Ihnen der Compiler das sagt.

Sie können in den XmlNodeList aus dem SelectNodes Verfahren wie so zurück Knoten durchlaufen:

foreach (XmlNode node in newBooks) 
{ 
    //... 
} 

Wie für Ihr Performance-Problem, oder vermeintlichen Leistungsproblem, empfehle ich Ihnen, eine Datei der gewünschten Größe zu laden und Benchmark es. Nur dann können Sie feststellen, ob Sie ein Leistungsproblem haben, da Sie es gemessen haben.