2016-06-21 10 views
1

In Zukunft werde ich 200.000 xml-Dateien lesen und aus jeder Datei einige Informationen erfassen. Ich muss einen Weg finden, so schnell wie möglich zu erhalten ...Gibt es eine effizientere Methode zum Lesen von XML-Feldern mit LINQ?

Meine XML:

<note> 
    <fields> 
     <name>john</name> 
     <lastname>doe</lastname> 
    </fields> 
    <info> 
     <chNFe>VALUE</chNFe> 
    </info> 
</note> 

I chNFe Knotens Wert

string xml = File.ReadAllText(@"C:\myxml.xml"); 
Regex.Replace(xml, @"[^\u0000-\u007F]", string.Empty); 

var doc = XDocument.Parse(xml); 
var matchingElements = doc.Descendants().Where(x => x.Name.LocalName == "chNFe"); 
string chave = matchingElements.First().Value; 

Console.WriteLine("Chave: " + chave); 

Gibt es eine effizientere erhalten möchten Methode zum Lesen von XML-Feldern mit LINQ?

+0

Um, Ihre XML-Beispiel nicht enthalten 'chNFe', ist es schwer zu sehen, zu machen, wie es ist relevant. (Es ist auch länger als nützlich - bitte schneiden Sie alles auf einen [mcve].) Kennen Sie den Namensraum, in dem das Element sein wird? Wenn dies der Fall ist, können Sie die Verwendung von 'Descendants (XName)' verwenden, indem Sie 'XName' aus einem' XNamespace' und einer 'Zeichenkette' konstruieren. –

+0

Der Knoten 'chNFe' existiert nicht in Ihrer Beispiel-XML. Ist das der richtige Knoten, nach dem Sie suchen? –

+7

Sie suchen auch nach Ausführungszeit-Effizienz? Sauberer Code? Geringer Platzbedarf? Ist es besonders ineffizient, wie es ist? Wenn ja, wie messen Sie das? –

Antwort

2

für den Abkömmling Knoten über XName Suche wird etwas schneller sein Grabbing Elemente direkt ist noch ein kleines bisschen schneller:

var chave = doc.Root.Element("info").Element("chNFe").Value; 

Die meiste Zeit, die Ihr Programm jedoch verbringt, wird es sein, von der Festplatte zu lesen und die XML-Dokumente zu analysieren, so dass Sie wahrscheinlich keine merklichen Gewinne erzielen werden, solange Sie LINQ to XML verwenden.

Here's mein Benchmark-Code. Und hier sind die Ergebnisse:

enter image description here

+0

Ich wäre gespannt auf Ihre Ergebnisse für das 'doc.Root.Element (" info "). Element (" chNFe "). Value;' version? Ich erwarte, dass es ähnlich wie Ihre '.Descendants (" chNFe ")' ist. –

+0

präsentiert den folgenden Fehler: Eine nicht behandelte Ausnahme vom Typ 'System.InvalidOperationException' in System.Core.dll aufgetreten Weitere Informationen: Die Sequenz enthält keine Elemente –

+0

@BrunoHenri: Verwenden Sie die tatsächliche Eingabe, die Sie im OP gegeben? Ich nehme an, Sie haben Namespaces oder etwas, das Sie aus dem Beispiel entfernt haben? Diese müssen der Descendants-Suche hinzugefügt werden. – StriplingWarrior

0

Was Sie haben, ist verdammt schnell, aber bohren durch den Baum scheint explizit noch schneller zu sein.

var doc = XDocument.Parse(xml); 
var chave = doc.Root.Element("info").Element("chNFe").Value; 

eine XPath-Abfrage verwenden könnte ein Weg sein, um die gleiche Leistung zu erhalten, aber Ihr Code vereinfachen:

var doc = XDocument.Parse(xml); 
var chave = doc.XPathSelectElement("/note/info/chNFe").Value; 
Auch

, werden Sie wahrscheinlich müssen separat den Dateiinhalt nicht lesen daraus Parsen ; Verwenden Sie XDocument.Load, um einen Pfad zu einer Datei anzugeben und lassen Sie sie lesen.

Meine Testergebnisse (1.000.000 Läufe von jeweils durchschnittlich Zeit):

var chave = doc.Descendants("chNFe").First().Value; 

aktualisieren:

1. LINQ -> Descendants() = 0.000019ms 
2. XPath     = 0.000024ms 
3. LINQ -> Element()  = 0.000004ms 
+0

Das ist komisch. Auf meinem Rechner scheint dieser Ansatz 7x länger zu dauern. Ich frage mich, was der Unterschied ist. – StriplingWarrior

+0

@StriplingWarrior: das ist neugierig. Ich benutzte LINQPad, C#, eine 'Stoppuhr', gemittelt ein paar Läufe von je einer Million Läufen. Ich bekam Zahlen wie "0,000104 ms" für die LINQ-Version und "0,000059 ms" für die XPath-Version. –

+0

Ja, es ist schwer zu sagen, ohne den spezifischen Code zu sehen, den du benutzt hast. Haben Sie versucht, die Benchmark LINQPad-Datei zu betrachten, die ich aus meiner Antwort verlinkt habe, um zu sehen, ob Sie die gleichen Ergebnisse erhalten? – StriplingWarrior

Verwandte Themen