2016-06-21 14 views
1

将来、私は200,000のXMLファイルを読み込み、各ファイルからいくつかの情報を取得します。私は可能な限り迅速に取得する方法を見つける必要がある...LINQを使用してXMLフィールドを読み取るより効率的な方法はありますか?

私のXML:私は

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); 

chNFeノードの値を取得したい

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

することは、より効率的ありLINQでXMLフィールドを読み取る方法?

+0

あの、あなたのサンプルXMLは、それは難しい、それは関連性の方法を確認すること、 'chNFe'が含まれていません。 (これも便利です) - すべてを[mcve]にカットしてください。要素の名前空間を知っていますか?もしそうなら、jusetは 'XNamespace'と' string'から 'XName'を構築して' Descendants(XName) 'を使うことができます。 –

+0

ノード 'chNFe'がサンプルXMLに存在しません。それはあなたが探している正しいノードですか? –

+7

また、実行時間の効率性をお探しですか?クリーンコードですか?スペースが少なくて済みますか?それはそれは特に非効率的ですか?もしそうなら、あなたはどのようにそれを測定していますか? –

答えて

2

XName介し子孫ノードの検索が若干速くなる。

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

更新:つかむ要素に直接まだ少し速いです:

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

しかし、あなたのプログラムが費やす時間の大部分は、ディスクからの読み込みとXML文書の解析に費やされるため、LINQ to XMLを使用している限り、おそらく目に見えるほどの利益を得ることはできません。

Here's私のベンチマークコード。そして、ここでの結果は以下のとおりです。

enter image description here

+0

'' doc.Root.Element( "info")の結果を見るのが好きなのですが、要素( "chNFe")。私はあなたの '.Descendants(" chNFe ")に似ていると期待しています。 –

+0

が次のエラーを表示しました:System.Core.dllで 'System.InvalidOperationException'型の未処理の例外が発生しました 追加情報:シーケンスに要素が含まれていません –

+0

@BrunoHenri:OPで入力した実際の入力を使用していますか?私はあなたが名前空間を持っているか、あなたがその例から外したものを持っていると思いますか?それらは、子孫の検索に追加する必要があります。 – StriplingWarrior

0

あなたが持っているものはかなり速いですが、明示的にツリーを掘り下げることはさらに速いようです。 XPathクエリを使用して

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

が同じパフォーマンスについて維持するための方法であることが、あなたのコードを簡素化することがあります

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

また、あなたはおそらく、それを解析することとは別にファイルの内容を読む必要はありません。 ; XDocument.Loadを使用してファイルへのパスを指定し、読み込みを行わせます。

私のテスト結果(各1,000,000ラン、平均時間):

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

それは変です。私のマシンでは、この方法は7倍長くかかるようです。私はその違いが何であるのだろうか。 – StriplingWarrior

+0

@StriplingWarrior:それは興味があります。私はLINQPad、C#、 'Stopwatch'を使用して、それぞれ数百万回実行しました。 LINQバージョンでは「0.000104 ms」、XPathバージョンでは「0.000059 ms」のような数字が得られました。 –

+0

ええ、あなたが使用した特定のコードを見ずに言うのは難しいです。あなたは私の答えからリンクしたベンチマークLINQPadファイルを見てみましたか、同じ結果が得られるかどうかを見てみましたか? – StriplingWarrior

関連する問題