0

I am trying to parse an ini file and grab specific key-value pairs,given a section name and key name. I use the following code, using Linq, and it works if I don't include the key name in its search but returns empty list if I do.

Sample ini section:

[INSTANCES]
NUMVTC=3
VTC=0,3330,ABCD,DESCR0
VTC=1,3331,EFGH,DESCR1
VTC=2,3332,IJKL,DESCR2

partial code to parse the file

List<IniEntry> vals = File.ReadLines(sMappingFilePath)
    .SkipWhile(line => !line.StartsWith("[instances]", 
        StringComparison.CurrentCultureIgnoreCase))
    .Skip(1)
    .TakeWhile(line => !string.IsNullOrEmpty(line) && line.StartsWith("vtc", StringComparison.CurrentCultureIgnoreCase))  // The "vtc" portion breaks it
    .Select(line => new IniEntry(line.Split('=')[0], line.Split('=')[1])).ToList();


public class IniEntry
{
    public string Key { get; set; }
    public string Value { get; set; }

    public IniEntry(string key, string val) {
        Key = key;
        Value = val;
    }
}

If I remove the part that says "line.StartsWith("vtc"...", it works and returns all key-value pairs under INSTANCES, including NUMVTC=3, which I want to skip.

I want to make this into a generic function that would return key-value pairs given a section name and key name.

Update

I modified the code, based on suggestions and comments, and made it to a generic function that takes .ini file path, section name and key name and return list on IniEntry objects.

   public static List<IniEntry> GetIniSectionDataList(string sIniFilePath, string sSection, string sKey)
    {
        List<IniEntry> ls = new List<IniEntry>();

        if (string.IsNullOrEmpty(sIniFilePath))
        {
            return ls;
        }
        // In case user enters **[blah** , or **blah]**
        sSection = sSection.Replace("[", string.Empty).Replace("]", string.Empty);
        sSection = "[" + sSection + "]";

        ls = File.ReadLines(sIniFilePath)
            .SkipWhile(line => !line.StartsWith(sSection, StringComparison.CurrentCultureIgnoreCase))
            .Where(line => line.StartsWith(sKey, StringComparison.CurrentCultureIgnoreCase))
            //.Skip(1)
            .TakeWhile(line => !string.IsNullOrEmpty(line))
            .Select(line => new IniEntry(line.Split('=')[0], line.Split('=')[1]))ToList();

        return ls;
    }

I call it using:

List<IniEntry> vals = TCLogFile.GetIniSectionDataList(sMappingFilePath, "instances", "vtc");
13
  • 1
    I'd add link to previous question and explain the problem which doesn't allow using library. Commented Jun 10 at 15:22
  • Yes, I tried to use ini-parser github.com/rickyah/ini-parser/tree/master but it didn;t work as it does not allow duplicates. Commented Jun 10 at 15:34
  • You need to use Where, here is a quick mockup. Commented Jun 10 at 15:35
  • Why do you want to skip NUMVTC if you want to make this "generic"? Just let it cook, then use GroupBy ? Commented Jun 10 at 15:35
  • 1
    I don't want to take responsibility for such flimsy (only works in this scenario) way of parsing ini-file. You can post your complete solution if you want to help future readers, but I doubt someone will find it easily, because nothing in title/body describes the problem clearly. Commented Jun 10 at 16:07

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.