2017-05-11 7 views
0

.cfgファイルを読み込もうとしています。設定ファイルからの値の解析と保存

私は正常に値を読み取り、リストに格納してからデータグリッドに格納しました。

私にとっては難しい部分は、この "linekey.INT.option"です。

linekey.6.label = Call Park 
linekey.6.line = 1 
linekey.6.pickup_value = 
linekey.6.type = 10 
linekey.6.value = 70 
linekey.7.label = Park 1 
linekey.7.line = 1 
linekey.7.pickup_value = 71 
linekey.7.type = 16 
linekey.7.value = 71 
linekey.8.label = Park 2 
linekey.8.line = 1 
linekey.8.pickup_value = 72 
linekey.8.type = 16 
linekey.8.value = 72 

私は「私はその後、私は何をすることができます何の問題に2列のリストに

 foreach (KeyValuePair<string, string> line in getLines) 
     { 
      ListViewDataItem item = new ListViewDataItem(); 
      listConfigOptions.Items.Add(item); 

      item[0] = line.Key; 
      item[1] = line.Value; 
     } 

     listConfigOptions.Columns[0].BestFit(); 
     listConfigOptions.Columns[1].BestFit(); 

をそれらを追加することはできません設定ファイルを読み込み、辞書に

 string[] fileLines = File.ReadAllLines(filepath); 
     StringBuilder sb = new StringBuilder(); 
     foreach (string line in fileLines) 
     { 
      sb.AppendLine(line); 
     } 

     tbConfigInput.Text = sb.ToString(); 

     Dictionary<string, string> getLines = new Dictionary<string, string>(); 

     foreach (string line in tbConfigInput.Lines) 
     { 
      if (line != "#!version:1.0.0.1") 
      { 
       if (line != "") 
       { 
        if (line.Contains("linekey")) 
        { 
         string[] splitLine = line.Split('='); 
         getLines.Add(splitLine[0], splitLine[1]); 
        } 
       } 
      } 
     } 

をすべてlinekeysを追加linekey.6またはlinekey.7に属するすべてのアイテムを取り出し、データテーブル内の自分の行に追加します。つまり、

Like Key | Label  |  Line  |  Extension  |  Type | Value 
    7   Park 1   1    71     16  71 

いくつかのアドバイスは大きな祝福になるでしょう。私はこれでほぼ一日中立ち往生しています。

ありがとうございます!

+1

の値を使用しています。配列とデータテーブルは仲介のステップとして素敵ですが、コアロジックが配列以外のものを使用している場合は、コードの読み込み/保守が難しくなります。 OOPを説明することは、SOの1つの質問の範囲を超えています。あなたが始められるように:すべてのフィールド(あなたのデータテーブルの例を含む)を含むクラス( 'MyClass')を作成し、' List Flater

+0

OOPは問題ではありません。私はこのテストコードをすべてテストして1つのクラスに集めています。 –

+1

面白いことはしていませんが、OOP_の_lackはまさにあなたの問題です。すべて同じプロパティセットを持つ反復可能なオブジェクトセット(ラインキー)がありますが、別々のプロパティを持つクラスにこれらのプロパティを置くことは避けています。あなたは目に見えない理由で難しいルートを選んでいます。あなたが解析を簡単にするためにクラスを使用することを避ける理由はありますか? – Flater

答えて

1

ような何かやっていないのはなぜ:

 DataTable dt = new DataTable(); 
     // define structure 
     dt.Columns.Add("Column1"); 
     dt.Columns.Add("Column2"); 
     // .... 
     dt.Columns.Add("ColumnN"); 
     // Add rows like this: 
     dt.Rows.Add(new object[] { "Column1 value", "Column2 value", .. , "ColumnN value" }); 

UPDATE:全サンプル

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.IO; 
using System.Linq; 
using System.Text; 

namespace MdeLoadTest 
{ 
    class DataRow 
    { 
     public string Label { get; set; } 
     public int Line { get; set; } 
     public int PickupValue { get; set; } 
     public int Type { get; set; } 
     public int Value { get; set; } 
    } 
    class ParseData 
    { 
     private List<DataRow> rows; 
     private int ReadSource(string file) 
     { 
      string[] fileLines = File.ReadAllLines(file); 


      rows = new List<DataRow>(); 
      string fieldInfo, fieldValue, fieldName; 
      int lineNumber, oldLineNumber; 
      string[] splitLine; 
      string[] fieldInfoParts; 
      oldLineNumber = -1; 
      DataRow row = null; 
      foreach (string line in fileLines) 
      { 

       splitLine = line.Split('='); 
       fieldInfo = splitLine[0];     
       fieldValue = splitLine.Count() >0? splitLine[1]:null; 
       fieldInfoParts = fieldInfo.Split('.'); 

       lineNumber = int.Parse(fieldInfoParts[1]); 
       fieldName = fieldInfoParts[2]; 

       if(lineNumber != oldLineNumber) 
       { 
        rows.Add(row); 
        row = new DataRow(); 
        oldLineNumber = lineNumber; 
       } 
       switch (fieldName) 
       { 
        case "label": 
         row.Label = fieldValue; 
         break; 
        case "line": 
         row.Line = int.Parse(fieldValue); 
         break; 
        case "pickup_value": 
         row.PickupValue = int.Parse(fieldValue); 
         break; 
        case "type": 
         row.Type = int.Parse(fieldValue); 
         break; 
        case "value": 
         row.Value = int.Parse(fieldValue); 
         break; 
        default: 
         throw new Exception($"Unknown key:{fieldName}"); 
       } 
      } 
      if (oldLineNumber != -1) 
      { 
       rows.Add(row); 
      } 
      return rows.Count; 
     } 

     DataTable table; 
     private void InitTable() 
     { 
      DataTable dt = new DataTable(); 
      // define structure 
      dt.Columns.Add("Label",typeof(string)); 
      dt.Columns.Add("Line", typeof(int)); 
      dt.Columns.Add("PickupValue", typeof(int)); 
      dt.Columns.Add("Type", typeof(int)); 
      dt.Columns.Add("Value", typeof(int)); 
     } 

     private void PopulateData() 
     { 
      foreach (var row in rows) 
      { 
       table.Rows.Add(row); 
      } 
     } 

     public DataTable Load(string sourceFile) 
     { 
      if (ReadSource(sourceFile) < 1) 
       return null; 
      InitTable(); 
      PopulateData(); 

      return table; 
     } 
    } 
} 
+0

私は既にその設定を持っている。問題はlinekey.INT.optionです。私はそれらを反復することができなければなりません。 (int) –

+0

あなたの構造が正しく理解されていれば:linekey。 = ? – Jester

+0

はい。それはまさに私が欲しいものです。私は知っている、私は知っている...私は物事を伝えて説明するのが最善ではない。 –

0

を私はあなたが持っている設定を解析する汎用ルーチンの下に書かれています。言うまでもなく、境界条件チェックを追加し、他のテストを行う必要があります。このコードは、ドットフォーマットのキーをconfigから解析し、それを後で簡単に検索できるように適切な構造に格納する方法を示しています。

class Configuration { 
    Dictionary<string, List<Dictionary<string, string>>> ParsedConfig = new Dictionary<string, List<Dictionary<string, string>>>(); 

    public Configuration(string fileName) { 
     ParseConfig(File.ReadLines(fileName)); 
    } 

    void ParseConfig(IEnumerable<string> lines) { 
     foreach (string line in lines) { 
      string[] splitLine = line.Split(new char[] { '=' }, 2); 
      if (splitLine.Length != 2) 
       continue; 

      var cfgKey = splitLine[0].Trim();  // you probably want to get rid of trailing and leading spaces 
      var cfgValue = splitLine[1].Trim(); 

      if (!cfgKey.Contains('.')) { // handle regular keys 
       var singularList = new List<Dictionary<string, string>>(); 
       ParsedConfig[cfgKey] = singularList; 
       singularList.Add(new Dictionary<string, string>()); 
       singularList[0][string.Empty] = cfgValue; 
       continue; 
      } 


      var keyParts = cfgKey.Split(new char[] { '.' }, 3); // break down the dotted key 
      if (keyParts.Length != 3) 
       continue; 


      if (!ParsedConfig.TryGetValue(keyParts[0], out var indexedConfigList)) 
       ParsedConfig[keyParts[0]] = indexedConfigList = new List<Dictionary<string, string>>(); 

      var index = int.Parse(keyParts[1]); 

      while (indexedConfigList.Count <= index) // add array slots for all indexes 
       indexedConfigList.Add(null); 

      var indexedConfig = indexedConfigList[index]; 
      if (indexedConfig == null) 
       indexedConfigList[index] = indexedConfig = new Dictionary<string, string>(); 

      indexedConfig[keyParts[2]] = cfgValue; 
     } 

    } 

    public Dictionary<string, string> GetGroupedConfig(string key, int index) { 
     if (ParsedConfig.TryGetValue(key, out var indexedConfigList) && indexedConfigList.Count > index) 
      return indexedConfigList[index]; 

     return null; 
    } 

    public string GetConfigValue(string key) { 
     string value = null; 
     if (ParsedConfig.TryGetValue(key, out var indexedConfigList) && indexedConfigList.Count > 0) 
      indexedConfigList[0].TryGetValue(string.Empty, out value); 
     return value; 
    } 

} 

Get*方法は、解析された構成から値を抽出する方法を示しています。

今、あなたはGet*関数を呼び出すことができ、必要に応じて、この問題は、最高のオブジェクト指向プログラミングによって対処することができ、あなたのDataTable

関連する問題