XMLとC#の両方が初めてです。 "proj_title" value = heat_runまたは他の可能な値に基づいて、関連する数値を取得するために特定のxmlファイルを効率的に解析する方法を見つけようとしています。たとえば、特定のテスト実行の期間を計算します(proj_end val-proj_startval)。
ex.xml:
<proj ID="2">
<proj_title>heat_run</proj_title>
<proj_start>100</proj_start>
<proj_end>200</proj_end>
</proj>
...この値はテスト実行ごとに固定されていないため、プロジェクトIDで検索することはできません。上記のファイルは巨大です:〜8mb、そしてproj_titleという名前の〜2000のタグがあります。最初にproj_title = "heat_run"ですべてのタグ名を検索し、次にC#を使用してこの特定のproj_titleのプロジェクトの開始値と終了値を取得する効率的な方法はありますか?
これが私の現在の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");
}
}
XPathを使用して、一致するすべてのノードを検索できます。次に例を示します。
XmlNodeList matches = xmlDoc.SelectNodes("proj[proj_title='heat_run']")
matches
には、基準に一致するすべてのproj
ノードが含まれます。 XPathの詳細: http://www.w3schools.com/xsl/xpath_syntax.asp
現代の基準では、8MBは実際にはそれほど大きくありません。個人的には、LINQ toXMLを使用します。
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")
});
XDocumentを使用し、LINQ APIを使用します。 http://msdn.Microsoft.com/en-us/library/bb387098.aspx
試してみた後のパフォーマンスが期待どおりでない場合は、saxパーサーを探す必要があります。 Saxパーサーはドキュメント全体をメモリにロードせず、メモリ内のすべてにxpath式を適用しようとします。イベント駆動型のアプローチでより効果的に機能し、場合によってはこれがはるかに高速になり、メモリをあまり使用しません。
おそらく周りに.NET用のsaxパーサーがあり、.NET用に自分で使用したことはありませんが、C++用に使用しました。