Click here to Skip to main content
Click here to Skip to main content

KeyValues

, 7 Apr 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Powerfull XML Alternative

Introduction

This library is inspired on "Source Engine" (HL2SDK) KeyValues Class
http://developer.valvesoftware.com/wiki/KeyValues_class (SourceSDK KeyValues Class)
It was used to save data and for send data to a entity.
It can have unlimited keys and subkeys inside a KeyValue
SourceSDK KeyValues metods: View [^]
Diferences:

   More Metods
   More easy to loop all keys
   Easy to update or add features

I decide make this library because i need something like that but XML was hard to me read in C#.
So i have make as alternative to XML, this is a easy to use library and very powerfull.
This also can be used as small databases, i have used KeyValues in "Counter-Strike Source" in my zombie mod to save each player status such:
damage taken, damage given, bullets spent, kills, deaths, name, steamid, and many others.

KeyValues Explorer:

This is a simple Application i do for explore, manage keyvalues, this also can generate source code for you use in your application.

kvExplorer.png (109 KB)
Screenshot of KeyValues Explorer App

Background 

This is my first project realease on CodeProject, so i wait people helpme improve article information and makeit clean and nice.
That class contain very metods and usefull things, fell free to explore it.

How its KeyValues file struct in disk?

"KeyValue Name"

{

    "key" "value"

    "other key" "other Value"

    "many other key" "value to key :P"

    // A comment to next SubKey or KeyValue ...

    "an subkey name"

    {

        "key" "value"

        "my key" "my value"

        "2key" "2value"

        NoSpaceKey WithoutQuotes

        UsingNoQuotes ASpaceWillDetermineNextValue

        // Lets load this file and addit as subkey to that KV

        #include "C:\test_include.txt"

        "Look An Other SubKey"

        {

            "my parent was" "an subkey name"

        }

    }

}

Help wanted

My english is not very good, so if any one wants help, can fix some english in my class and fix XML documentation for each metod, and create summary for missing metods.
Thanks if you can help

Using the Code

A brief description of how to use the article or code. The class names, the methods and properties, any tricks or tips.

Creating a simple KeyValue, and save it to disk:

            // Creating KeyValue
            KeyValues kv = new KeyValues("namespace");
            kv.Comment = "Testing comments (Optional)";
            kv.SetString("my_dinner", "chiken");
            
            // Get my dinner and print to console
            Console.WriteLine("My Dinner Was: {0}", kv.GetValue("my_dinner"));

            // Now lets create a sub key for our KeyValue
            // And lets use constructor to SetString, same as: subKV.SetString("best", "CodeProject.com");
            KeyValues subKV = new KeyValues("my_friends", "best", "CodeProject.com", null);
            kv.AddSubKey(subKV); // Add subkv to main KeyValue
            // Now lets save our class to Disk
            kv.SaveToFile(@"C:\kv_test.txt");

Load last KeyValue from Disk and read thier values:

            if (!kv.LoadFromFile(@"C:\kv_test.txt")) return; // Fail on load
            // retriving subkv
            KeyValues subkv = kv.FindKey("my_friends");
            if (subkv == null) return; // Subkey not exists!

            // Print Data
            Console.WriteLine("My Dinner Was: {0} And my best friend is: {1}", kv.GetValue("my_dinner"), subkv.GetValue("best"));

            // Set an extra value to know last time KV was been loaded
            kv.SetDateTime("lastLoadedTime", DateTime.Now);

Loop all Key, Values and SubKeys:

        // Metod 1, use While
        void foreachKVMetod1(KeyValues kv)
        {
            KeyValues fkv;
            KeyValuesData kvData;
            // Loop all Keys and Values
            while ((kvData = kv.GetNextKeyValue()) != null) 
            {
                if (!string.IsNullOrEmpty(kvData.Comment)) // Print comment if not null
                    Console.WriteLine("// {0}", kvData.Comment);
                Console.WriteLine("[{0}] = {1}", kvData.Key, kvData.Value);
            }
            // Loop all SubKeys
            while ((fkv = kv.GetNextSubKey()) != null)
            {
                if (!string.IsNullOrEmpty(fkv.Comment)) // Print comment if not null
                    Console.WriteLine("// {0}", fkv.Comment);
                Console.WriteLine("\"{0}\"", fkv.Name);
                Console.WriteLine("{");
                foreachKVMetod1(fkv); // Continue foreach all subkeys inside
            }
            Console.WriteLine("}");
        }

        // Metod 2, use for
        void foreachKVMetod2(KeyValues kv)
        {
            for (int i = 0; i < kv.KeyNameValues.Count; i++)
            {
                if (!string.IsNullOrEmpty(kv.KeyNameValues[i].Comment)) // Print comment if not null
                    Console.WriteLine("// {0}", kv.KeyNameValues[i].Comment);
                Console.WriteLine("[{0}] = {1}", kv.KeyNameValues[i].Key, kv.KeyNameValues[i].Value);
            }
            // Loop all SubKeys
            for (int i = 0; i < kv.KeyChilds.Count; i++)
            {
                if (!string.IsNullOrEmpty(kv.KeyChilds[i].Comment)) // Print comment if not null
                    Console.WriteLine("// {0}", kv.KeyChilds[i].Comment);
                Console.WriteLine("\"{0}\"", kv.KeyChilds[i].Name);
                Console.WriteLine("{");
                foreachKVMetod1(kv.KeyChilds[i]); // Continue foreach all subkeys inside
            }
            Console.WriteLine("}");
        }

        foreachKVMetod1(kv);
        foreachKVMetod2(kv);

Variable or class names should be wrapped in <code> tags like this.

Points of Interest

Math Operators in KeyValues:

kv += kv1 This will AddSubKey kv1 to Main kv
kv -= kv1 This will RemoveSubKey kv1 from Main kv
kv += "string" This will AddSubKey string_name to Main kv
kv -= "string" This will RemoveSubKey string_name from Main kv
kv += KeyValuesData This will Set KeyValuesData key and value to Main kv
kv -= KeyValuesData This will Remove KeyValuesData key and value from Main kv

Inside a file for load using KeyValues library you can include other keyvalues files:

"Root"

{

    // Lets load a SubKv into "Root" KeyValue

    #include "C:/filename.txt"


    "me"		"you :P"

    "bool test"		"True"

    "byte test"		"1"

    "char test"		"A"

    "decimal test"		"10,1"

    "double test"		"10,1"

    "float test"		"10,1"

    "short test"		"5000"

    "int test"		"500000000"

    "long test"		"5000000000000000000"

    "date test"		"25-03-2009 1:16:31"

}

History

v1.0.0.0:

First Realease 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

Comments and Discussions

 
QuestionLoading this as an Assembly in 3ds Max PinmemberShawn Olson22-Jan-13 8:51 
I'm trying to integrate this into some of my 3ds Max tools for Source and cannot seem to figure out how to load this as an assembly into 3ds Max with MAXScript and DOTNET.
 
Any Advice?
 
When using this code:
 
WallWormKVAssembly = dotnet.loadAssembly "C:\KeyValues\bin\Release\KeyValues.dll"
WallWormKV = dotnetClass "KeyValues"
WallWormKVAssembly.FullName
 
I will get this information:
 
WallWormKVAssembly:  dotNetObject:System.Reflection.RuntimeAssembly
WallWormKV: undefined
WallWormKVAssembly: "KeyValues, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
 
I cannot figure out how to create a KeyValues Object in MAXScript and utilize it. WallWormKV is undefined. I am still novice with .NET so perhaps the class isn't written to be accessible this way?
AnswerRe: Loading this as an Assembly in 3ds Max PinmemberShawn Olson22-Jan-13 10:51 
Generalgood first article PinmemberDonsw12-May-09 5:39 
GeneralCongrats PinmemberNeville Franks7-Apr-09 20:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141216.1 | Last Updated 7 Apr 2009
Article Copyright 2009 by Tiago Conceição
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid