KdlSharp 1.0.0
dotnet add package KdlSharp --version 1.0.0
NuGet\Install-Package KdlSharp -Version 1.0.0
<PackageReference Include="KdlSharp" Version="1.0.0" />
<PackageVersion Include="KdlSharp" Version="1.0.0" />
<PackageReference Include="KdlSharp" />
paket add KdlSharp --version 1.0.0
#r "nuget: KdlSharp, 1.0.0"
#:package KdlSharp@1.0.0
#addin nuget:?package=KdlSharp&version=1.0.0
#tool nuget:?package=KdlSharp&version=1.0.0
KdlSharp

A feature-rich C# library for KDL (KDL Document Language) with strong v2.0 specification support.
Features
- POCO Serialization: Map .NET objects to KDL and back with
KdlSerializer - KDL v2.0 Support: All string types, number formats, and modern syntax
- Document Model API: Parse and manipulate KDL documents programmatically
- Query Language: CSS-selector-like queries for finding nodes
- Schema Validation: Validate documents against schemas with full
refresolution support - Special Numbers: Full support for
#inf,#-inf, and#nanwith proper round-trip semantics - Zero Dependencies: No external dependencies in core library
- Cross-Platform: .NET Standard 2.1 compatible
Installation
dotnet add package KdlSharp
Examples
1. Parse a KDL Document
using KdlSharp;
var doc = KdlDocument.Parse(@"
server host=""localhost"" port=8080 {
database connection=""postgres://localhost/mydb""
}
");
var server = doc.Nodes[0];
Console.WriteLine(server.GetProperty("host")?.AsString()); // "localhost"
Console.WriteLine(server.GetProperty("port")?.AsInt32()); // 8080
2. Serialize Objects to KDL
using KdlSharp.Serialization;
public record ServerConfig(string Host, int Port, bool UseSsl);
var config = new ServerConfig("localhost", 8080, true);
var serializer = new KdlSerializer(new KdlSerializerOptions
{
RootNodeName = "server",
PropertyNamingPolicy = KdlNamingPolicy.KebabCase
});
string kdl = serializer.Serialize(config);
// server host="localhost" port=8080 use-ssl=#true
3. Deserialize KDL to Objects
var kdl = @"server host=""localhost"" port=8080 use-ssl=#true";
var config = serializer.Deserialize<ServerConfig>(kdl);
Note: Circular references are not supported. Serializing an object graph containing cycles (e.g., A → B → A) throws
KdlSerializationException. To serialize graphs with cycles, break them first using reference IDs or other patterns.
4. Build Documents Programmatically
var doc = new KdlDocument();
doc.Nodes.Add(
new KdlNode("package")
.AddArgument("my-app")
.AddProperty("version", "1.0.0")
.AddChild(new KdlNode("author").AddArgument("Alice"))
);
string kdl = doc.ToKdlString();
5. Query Nodes
using KdlSharp.Query;
var doc = KdlDocument.Parse(@"
package {
dependencies { lodash ""^4.0"" }
dev-dependencies { jest ""^29.0"" }
}
");
// Find all dependency nodes
var deps = KdlQuery.Execute(doc, "package >> dependencies");
6. Validate Against Schema
using KdlSharp.Schema;
using KdlSharp.Schema.Rules;
var schema = new SchemaDocument(
new SchemaInfo { Title = "Config Schema" },
nodes: new[] {
new SchemaNode("server", properties: new[] {
new SchemaProperty("port", required: true, validationRules: new[] {
new GreaterThanRule(0), new LessThanRule(65536)
})
})
}
);
var result = KdlSchema.Validate(doc, schema);
if (!result.IsValid)
foreach (var error in result.Errors)
Console.WriteLine($"{error.Path}: {error.Message}");
7. Parse Legacy v1 Documents
var settings = new KdlParserSettings { TargetVersion = KdlVersion.V1 };
var doc = KdlDocument.Parse("node true false null", settings);
8. Serializer Options
var options = new KdlSerializerOptions
{
// Custom root node name (default: "root")
RootNodeName = "config",
// Naming policy: CamelCase, PascalCase, SnakeCase, KebabCase, None (default: KebabCase)
PropertyNamingPolicy = KdlNamingPolicy.KebabCase,
// Include null values in output (default: false)
IncludeNullValues = true,
// Add type annotations like (i32), (string), (bool) (default: false)
WriteTypeAnnotations = true,
// Write simple values as arguments vs properties (default: true)
UseArgumentsForSimpleValues = true,
// Flatten single-child objects into parent node (default: false)
FlattenSingleChildObjects = false,
// Target KDL version: V1 uses bare true/false/null, V2 uses #true/#false/#null (default: V2)
TargetVersion = KdlVersion.V2
};
9. Version Markers
When formatting KDL documents, you can include a version marker at the start of the output:
using KdlSharp.Formatting;
using KdlSharp.Settings;
var settings = new KdlFormatterSettings
{
IncludeVersionMarker = true, // Emit /- kdl-version N at start
TargetVersion = KdlVersion.V2
};
var formatter = new KdlFormatter(settings);
var kdl = formatter.Serialize(doc);
// Output: /- kdl-version 2
// node #true ...
10. Preserving String Formatting
By default, all strings are serialized as quoted strings. To preserve the original string format (identifier, quoted, raw, or multi-line) from parsing:
using KdlSharp.Formatting;
using KdlSharp.Settings;
// Parse a document with various string types
var doc = KdlDocument.Parse("node identifier-value #\"raw string\"# \"quoted\"");
// Enable PreserveStringTypes to maintain original formatting
var settings = new KdlFormatterSettings { PreserveStringTypes = true };
var formatter = new KdlFormatter(settings);
var kdl = formatter.Serialize(doc);
// Output: node identifier-value #"raw string"# "quoted"
Raw strings preserve their original hash count delimiter during round-tripping:
// Parse a raw string with multiple hashes
var doc = KdlDocument.Parse("node ##\"contains \"# pattern\"##");
// The hash count is preserved when serializing with PreserveStringTypes
var settings = new KdlFormatterSettings { PreserveStringTypes = true };
var formatter = new KdlFormatter(settings);
var kdl = formatter.Serialize(doc);
// Output: node ##"contains "# pattern"##
Note: When constructing
KdlStringvalues programmatically (not from parsing), they default toKdlStringType.Quoted. Specify the string type in the constructor to use other formats:new KdlString("value", KdlStringType.Identifier). For raw strings, use the static helper method for convenience:
// Create a simple raw string (hash count computed automatically)
var raw = KdlString.Raw(@"C:\path\to\file");
// Create a raw string with explicit hash count
var rawWithHashes = KdlString.Raw("contains \"# pattern", hashCount: 2);
// Create a multi-line raw string
var rawMultiLine = KdlString.Raw("line1\nline2", multiLine: true);
Streaming API
Reading from Streams
Parse documents directly from streams with the leaveOpen parameter to control stream lifetime:
using var fileStream = File.OpenRead("config.kdl");
// Parse from stream, closing it after parsing (default)
var doc = KdlDocument.ParseStream(fileStream);
// Or keep the stream open for further operations
var doc = KdlDocument.ParseStream(fileStream, leaveOpen: true);
Async versions are available for all stream operations:
var doc = await KdlDocument.ParseStreamAsync(fileStream, cancellationToken: token);
await doc.WriteToAsync(outputStream, leaveOpen: true);
Token-by-Token Reading
For scenarios requiring token-level control over parsing, use KdlReader:
using KdlSharp.Parsing;
using var reader = new StringReader(kdlText);
using var kdlReader = new KdlReader(reader);
while (kdlReader.Read())
{
Console.WriteLine($"[{kdlReader.Line}:{kdlReader.Column}] {kdlReader.TokenType}");
}
Async Streaming Serialization
For memory-efficient serialization of large sequences, use SerializeStreamAsync:
// Serialize an async sequence directly to a stream
await serializer.SerializeStreamAsync(GetEventsAsync(), outputStream);
async IAsyncEnumerable<Event> GetEventsAsync()
{
// Objects are serialized one at a time as they are yielded
await foreach (var evt in eventSource.ReadAsync())
yield return evt;
}
The streaming serializer supports cancellation tokens and respects serializer options like TargetVersion.
Note: All parsing methods (including
ParseStream,ParseStreamAsync, andKdlReader) read the entire input into memory before tokenizing. The "streaming" APIs provide convenient stream-based interfaces but do not perform incremental parsing. For typical configuration files (under 1MB), this is not a concern. See AsyncOperations.cs for detailed examples.
Requirements
- .NET Standard 2.1 or higher
- Compatible with .NET 6+, .NET Framework 4.7.2+, Mono, Xamarin
More Resources
- KdlSharp.Demo - Working examples of all features
- KDL Website - Official KDL documentation
- AGENTS.md - Development guide and contributing
License
MIT License - see LICENSE for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 656 | 12/1/2025 |