2013-06-03 18 views
12

私はXMLとC#の両方が新しいです。私は、適切な数値を取得するために、与えられたXMLファイルを効率的に解析する方法を見つけようとしています。 "proj_title" value = heat_runまたは他の可能な値に基づいています。たとえば、特定のテスト実行の期間を計算する(proj_end val-proj_start val)。C#を使用してXMLファイルを解析する?

ex.xml: 

<proj ID="2"> 
     <proj_title>heat_run</proj_title> 
     <proj_start>100</proj_start> 
     <proj_end>200</proj_end> 
</proj> 

... この値は、テスト実行にテストランから固定されていないので、私たちは、PROJ IDで検索することはできません。上記のファイルは巨大です:〜8MB、〜proj_titleという名前の〜2000個のタグがあります。 proj_title = "heat_run"というタグ名をすべて見つけて、この特定のproj_titleのproj開始値と終了値をC#で検索する効率的な方法はありますか?

は、ここに私の現在のC#のコードです:

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"); 
    } 
}  
+0

[このリンク](http://support.microsoft.com:XPathの詳細については、こちらをご覧ください/ kb/815813)がお手伝いします –

答えて

8

次の例のように、一致するすべてのノードを見つけるために、XPathを使用することができます。

XmlNodeList matches = xmlDoc.SelectNodes("proj[proj_title='heat_run']")

matchesには、すべてのノードが基準と一致するprojが含まれます。 ...あなたがオブジェクトにあなたのXMLを回すことができる場所私はXMLシリアル化を使用して幸運をたくさん持っていたhttp://www.w3schools.com/xsl/xpath_syntax.asp

MSDN Documentation on SelectNodes

3

使用XDocumentとLINQ APIを使用しています。 http://msdn.microsoft.com/en-us/library/bb387098.aspx

パフォーマンスが期待どおりでない場合は、サックスパーサーを検索する必要があります。 Saxパーサーは、ドキュメント全体をメモリに読み込まず、メモリ内のすべてにxpath式を適用しようとします。イベント駆動型のアプローチではより多くの機能を果たしますが、場合によってはこれは非常に高速で、多くのメモリを使用することはありません。

.NET用のサックスパーサーはおそらく存在しますが、.NET用にはそれを自分で使用していませんが、C++用にしました。

14

8MBは現代の基準では本当にあまり大きくありません。

: -

代替クエリ

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

(。それはあなたが質問に基づいて何をする必要があるか本当にはっきりしていない明らかに独自の要件にこれを調整する):個人的に私はXMLにLINQを使用したいです

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") 
          }); 
+0

これは私を助けました!私はちょうど1つ以上の条件を追加する必要があります。例えばxの先祖を参照するLINQ/C#のオプションがありますか? Where(x =>(string)x == "heat_run" &&(string)x.Ancestor == "heat_test"のように)私はこれを試して、それは動作しませんでしたか? – jerryh91

+0

@ jerryh91:あなたは 'Parent'を使うことができますが、通常は別の方法で動作します。特定の子を持つ親を見つけます。 –

関連する問題