2017-05-11 1 views
0

Ich versuche, eine .cfg-Datei zu lesen.Analysieren und Speichern von Werten aus einer Konfigurationsdatei

Ich habe erfolgreich Werte gelesen und in einer Liste und dann in einem Datagrid gespeichert.

Der schwierige Teil für mich, ist diese "Linekey.INT.option", wie Sie unten sehen können.

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 

Ich lese die Config-Datei und fügen Sie alle linekeys zu einem Wörterbuch

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

ich sie in ein 2 Spaltenliste fügen Sie dann kann kein Problem

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

Was kann ich‘ t scheinen zu tun, nehmen Sie alle Elemente, die Linekey.6 oder Linekey.7 gehören und fügen Sie sie zu ihrer eigenen Zeile in einer Datentabelle, dh:

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

Einige Ratschläge wären ein großer Segen. Ich bin jetzt fast einen ganzen Tag drangeblieben.

Danke SO!

+1

Dieses Problem kann am besten durch die objektorientierte Programmierung angesprochen werden. Arrays und Datatables sind ein guter Zwischenschritt, aber sie erschweren das Lesen/Pflegen von Code, wenn Ihre Kernlogik nur Arrays verwendet. Das Exportieren von OOP geht weit über den Rahmen einer einzelnen SO-Frage hinaus. Um Ihnen den Einstieg zu erleichtern: Erstellen Sie eine Klasse ('MyClass'), die das gesamte Feld enthält (vgl. Das Beispiel Ihrer Datentabelle) und generieren Sie dann eine' List Flater

+0

OOP ist nicht das Problem. Ich staple all diesen Testcode in einer Klasse zum Testen auf. –

+1

Nicht versuchen, witzig zu sein, aber _lack of OOP_ ist genau dein Problem hier. Sie haben einen wiederholbaren Satz von Objekten (Linekey), die alle die gleichen Eigenschaften haben, aber Sie vermeiden es, diese in eine Klasse mit separaten Eigenschaften zu setzen. Du wählst den harten Weg ohne erkennbaren Grund. Gibt es einen Grund, warum Sie die Verwendung von Klassen zum leichteren Parsen vermeiden? – Flater

Antwort

1

Warum tun nicht so etwas wie:

 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: Voll Probe

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

Ich habe dieses Setup bereits. Problem ist die Linekey.INT.option. Ich muss in der Lage sein, sie zu durchlaufen. (der Int) –

+0

Wenn ich Sie richtig verstehe, ist Ihre Struktur: Linekey. . = ? – Jester

+0

Ja. Genau das möchte ich. Ich weiß, ich weiß ... Ich bin nicht der Beste darin, Dinge zu kommunizieren und zu erklären. –

0

ich unter einer generischen Routine geschrieben haben, die Konfiguration, die Sie haben zu analysieren. Unnötig zu erwähnen, dass Sie Randbedingungsprüfungen hinzufügen und andere Tests durchführen müssen. Der Code zeigt, wie ein gepunkteter Formatschlüssel von der Konfiguration aus analysiert und in einer geeigneten Struktur gespeichert wird, um später leicht abgerufen werden zu können.

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

} 

Die Get* Verfahren zeigen, wie die Werte von der geparsten Konfiguration zu extrahieren.

Jetzt können Sie die Get* Funktionen aufrufen und die Werte verwenden, je nach Bedarf in Ihrem DataTable

Verwandte Themen