KeyValues





3.00/5 (2 votes)
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.
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