2017-01-17 6 views
0

私はC#でプログラミングを始めたばかりで、いくつかのcsvファイルのデータを1つのXMLファイルに処理するにはいくつかの問題があります。大きなcsvファイルをマージして1つのxmlファイルに変換する方法

私は次のように見えるしているCSVファイル:

"ID","NODE","PROCESS_STATE","TIME_STAMP","PREV_TIME_STAMP","CALCULATED" 
206609474,2175,47,31.03.2015 00:01:25,31.03.2015 00:01:24,1 
206609475,2175,47,31.03.2015 00:02:25,31.03.2015 00:01:25,1 
206609476,2175,47,31.03.2015 00:03:25,31.03.2015 00:02:25,1 

私は私の計算のためには重要ではありませんすべてのエントリ(たとえばを削除する最初のステップでは、私は特定の日付を含んでいないすべてのファイルを削除)、各ファイルを再度保存します。

2番目の手順では、準備したすべてのファイル(〜100)を1つの大きなcsvファイルにマージします。

これまではすべてが非常に良好で高速でした。

最後のステップは、次の形式のXMLファイルにCSVファイルを変換することです:

<data-set> 
    <PDA_DATA> 
    <ID>484261933</ID> 
    <NODE>2190</NODE> 
    <PROCESS_STATE>18</PROCESS_STATE> 
    <PREV_TIME_STAMP>05.05.2016 22:53:41</PREV_TIME_STAMP> 
    </PDA_DATA> 
    <PDA_DATA> 
    <ID>484261935</ID> 
    <NODE>2190</NODE> 
    <PROCESS_STATE>47</PROCESS_STATE> 
    <PREV_TIME_STAMP>06.05.2016 00:44:17</PREV_TIME_STAMP> 
    </PDA_DATA> 
</data-set> 

私は要素(「TIME_STAMP」、「計算」)と、さらに多くを削除見ることができるようにまた、エントリ "TIME_STAMP"が "PREV_TIME_STAMP"に等しいすべてのエントリを削除します。私は次のコードでこれをやっています:

string[] csvlines = File.ReadAllLines("All_Machines.csv"); 

XElement xml = new XElement("data-set", 
    from str in csvlines 
    let columns = str.Split(',') 
    select new XElement("PDA_DATA", 
     new XElement("ID", columns[0]), 
     new XElement("NODE", columns[2]), 
     new XElement("PROCESS_STATE", columns[5]), 
     new XElement("TIME_STAMP", columns[6]), 
     new XElement("PREV_TIME_STAMP", columns[9]), 
     new XElement("CALCULATED", columns[10]))); 

// Remove unneccessray elements 

xml.Elements("PDA_DATA") 
    .Where(e => 
     e.Element("TIME_STAMP").Value.Equals(e.Element("PREV_TIME_STAMP").Value)) 
      .Remove(); // Remove entries with duration = 0 

xml.Elements("PDA_DATA").Elements("TIME_STAMP").Remove(); 
xml.Elements("PDA_DATA").Elements("PREV_PROCESS_STATE").Remove(); 
xml.Elements("PDA_DATA").Elements("CALCULATED").Remove(); 
xml.Save("All_Machines.xml"); 

これは私の問題です。 TimeStampがPrevTimeStampと等しい要素を削除する行を除外すると、すべてがかなり良く高速に機能します。 しかし、このコマンドでは、時間がかかり、小さなcsvファイルでしか動作しません。

私はリソース効率の良いプログラミングについて知らないので、あなたの誰かが問題がどこにあるのか、それをどうやって改善するのか教えてくれて本当にうれしいです。

+0

多分あなたは、あなたが並列でlinqクエリを実行できるかどうかを確認することができますhttps://msdn.microsoft.com/en-us/library/dd460688(v=vs) .110).as px – Bassie

+0

そこに何も見つかりませんでした。しかし、私はどこでも条件が満たされている要素だけが追加されたscond XMLファイルを作成しようとしました。これははるかに速くて、100MBのCSVファイルを処理できます。以前は不可能でした! – Aiye

+0

上記のコードとcsvが指定されたxmlを作成していますか?そのコードをcsvに対して実行すると、私のxmlには1つの 'PDA_DATA'要素と' ID'、 'NODE'などの文字列が含まれています。 – Bassie

答えて

0

これは、はるかに高速にうまくいく:まだ

string[] csvlines = File.ReadAllLines("All_Machines.csv"); 

    XElement xml = new XElement("data-set", 
     from str in csvlines 
     let columns = str.Split(',') 
     select new XElement("PDA_DATA", 
      new XElement("ID", columns[0]), 
      new XElement("NODE", columns[1]), 
      new XElement("PROCESS_STATE", columns[2]), 
      new XElement("TIME_STAMP", columns[3]), 
      new XElement("PREV_TIME_STAMP", columns[4]), 
      new XElement("CALCULATED", columns[5]), 
          ) 
          ); 

    // Remove unneccessray elements 

     XElement xml2 = new XElement("data-set",          
       from el in xml.Elements() 
       where (el.Element("TIME_STAMP").Value != (el.Element("PREV_TIME_STAMP").Value)) 
       select el 
       ); 

     xml2.Elements("PDA_DATA").Elements("TIME_STAMP").Remove(); 
     xml2.Elements("PDA_DATA").Elements("PREV_PROCESS_STATE").Remove(); 
     xml2.Elements("PDA_DATA").Elements("CALCULATED").Remove(); 
     xml2.Save("All_Machines.xml"); 

ない150メガバイト以上のCSVファイル・サイズのための完璧な...任意のより良い提案を? Cinchoo ETL

0

- オープンソースのフレームワークには、出力XMLが

<data-set> 
    <PDA_DATA> 
    <ID>206609474</ID> 
    <NODE>2175</NODE> 
    <PROCESS_STATE>47</PROCESS_STATE> 
    <PREV_TIME_STAMP>31.03.2015 00:01:25</PREV_TIME_STAMP> 
    </PDA_DATA> 
    <PDA_DATA> 
    <ID>206609475</ID> 
    <NODE>2175</NODE> 
    <PROCESS_STATE>47</PROCESS_STATE> 
    <PREV_TIME_STAMP>31.03.2015 00:02:25</PREV_TIME_STAMP> 
    </PDA_DATA> 
    <PDA_DATA> 
    <ID>206609476</ID> 
    <NODE>2175</NODE> 
    <PROCESS_STATE>47</PROCESS_STATE> 
    <PREV_TIME_STAMP>31.03.2015 00:03:25</PREV_TIME_STAMP> 
    </PDA_DATA> 
</data-set> 

開示のように見える

using (var csv = new ChoCSVReader("NodeData.csv").WithFirstLineHeader(true) 
    .WithFields("ID", "NODE", "PROCESS_STATE", "PREV_TIME_STAMP")) 
{ 
    using (var xml = new ChoXmlWriter("NodeData.xml").WithXPath("data-set/PDA_DATA")) 
     xml.Write(csv); 
} 

以下のように数行のコードで迅速にCSV/XML大容量のファイルを読み書きすることができます:私はこのライブラリの作者です

関連する問題