https://github.com/adomorn/structuredjson
StructuredJson is a library for working with complex JSON data structures in a more structured and type-safe way. It provides tools to validate, transform, and manipulate deeply nested JSON data efficiently, making it easier to handle configuration files, API responses, and data interchange formats.
https://github.com/adomorn/structuredjson
class-library dotnet json nuget-package
Last synced: 8 months ago
JSON representation
StructuredJson is a library for working with complex JSON data structures in a more structured and type-safe way. It provides tools to validate, transform, and manipulate deeply nested JSON data efficiently, making it easier to handle configuration files, API responses, and data interchange formats.
- Host: GitHub
- URL: https://github.com/adomorn/structuredjson
- Owner: adomorn
- License: mit
- Created: 2025-06-04T08:02:38.000Z (about 1 year ago)
- Default Branch: development
- Last Pushed: 2025-06-29T14:23:28.000Z (12 months ago)
- Last Synced: 2025-07-05T07:49:02.799Z (12 months ago)
- Topics: class-library, dotnet, json, nuget-package
- Language: C#
- Homepage:
- Size: 108 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# StructuredJson
[](https://www.nuget.org/packages/StructuredJson/)
[](https://opensource.org/licenses/MIT)
[](https://dotnet.microsoft.com/)
[](https://github.com/adomorn/StructuredJson/actions/workflows/release.yml)
[](https://github.com/adomorn/StructuredJson/actions/workflows/sonarcloud.yml)
A powerful .NET library for creating, reading, and updating JSON objects using a path-based API. Built with `Dictionary` as the underlying data structure and `System.Text.Json` for modern, high-performance serialization.
## β¨ Features
- **π Path-based API**: Intuitive path syntax for navigating and manipulating JSON structures
- **π Cross-platform**: Full compatibility with .NET Standard 2.0, .NET 8, and .NET 9
- **β‘ High Performance**: Uses `System.Text.Json` for optimal serialization performance
- **π Smart Type Conversion**: Intelligent conversion between strings, numbers, and complex types
- **π Full CRUD Operations**: Complete Create, Read, Update, Delete capabilities with robust error handling
- **π― Sparse Array Support**: Efficient handling of arrays with automatic null-filling for gaps
- **π Unicode Ready**: Full support for international characters, emojis, and special symbols
- **π Path Validation**: Comprehensive validation with meaningful error messages
- **π Path Discovery**: List all paths and values in your JSON structure
- **π Well Documented**: Complete XML documentation and extensive unit test coverage
## π¦ Installation
Install via NuGet Package Manager:
```bash
dotnet add package StructuredJson
```
Or via Package Manager Console:
```powershell
Install-Package StructuredJson
```
Or via PackageReference in your `.csproj`:
```xml
```
## π Quick Start
```csharp
using StructuredJson;
// Create a new instance
var sj = new StructuredJson();
// Set values using intuitive path syntax
sj.Set("user:name", "John Doe");
sj.Set("user:age", 30);
sj.Set("user:isActive", true);
sj.Set("user:addresses[0]:city", "Ankara");
sj.Set("user:addresses[0]:country", "Turkey");
sj.Set("user:addresses[1]:city", "Istanbul");
// Get values with automatic type conversion
var name = sj.Get("user:name"); // "John Doe"
var age = sj.Get("user:age"); // 30
var isActive = sj.Get("user:isActive"); // true
var city = sj.Get("user:addresses[0]:city"); // "Ankara"
// Convert to beautifully formatted JSON
var json = sj.ToJson();
Console.WriteLine(json);
// List all paths and values
var paths = sj.ListPaths();
foreach (var kvp in paths)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
```
## π Path Syntax
StructuredJson uses an intuitive and powerful path syntax with comprehensive validation:
### Object Properties
Use `:` to navigate object properties:
```csharp
sj.Set("user:name", "John"); // user.name
sj.Set("config:database:host", "localhost"); // config.database.host
sj.Set("app:settings:theme", "dark"); // app.settings.theme
```
### Array Elements
Use `[index]` to access array elements:
```csharp
sj.Set("users[0]", "John"); // users[0]
sj.Set("items[2]:name", "Product"); // items[2].name
sj.Set("data[5]:values[3]", 42); // data[5].values[3]
```
### Complex Nested Paths
Combine objects and arrays seamlessly:
```csharp
sj.Set("user:addresses[0]:coordinates:lat", 39.9334);
sj.Set("products[1]:reviews[0]:rating", 5);
sj.Set("config:servers[2]:endpoints[0]:url", "https://api.example.com");
```
### Path Validation
The library provides comprehensive path validation:
- β
`"user:name"` - Valid object property
- β
`"items[0]"` - Valid array element
- β
`"data:list[5]:value"` - Valid nested path
- β `"items[]"` - Invalid: empty array index
- β `"items[-1]"` - Invalid: negative index
- β `"items[abc]"` - Invalid: non-numeric index
## π§ API Reference
### Constructors
```csharp
// Create empty structure
var sj = new StructuredJson();
// Create from JSON string (with comprehensive validation)
var sj = new StructuredJson(jsonString);
```
### Core Methods
#### Set(string path, object? value)
Sets a value at the specified path, creating nested structures automatically:
```csharp
sj.Set("user:name", "John");
sj.Set("user:addresses[0]:city", "Ankara");
sj.Set("items[5]", "value"); // Creates sparse array with nulls at 0-4
// Supports all data types
sj.Set("numbers:int", 42);
sj.Set("numbers:decimal", 123.45m);
sj.Set("flags:isActive", true);
sj.Set("data:nullValue", null);
sj.Set("text:unicode", "π TΓΌrkΓ§e δ½ ε₯½");
```
**Throws**: `ArgumentException` for invalid paths
#### Get(string path) / Get(string path)
Retrieves values with intelligent type conversion:
```csharp
// Basic retrieval
var name = sj.Get("user:name"); // Returns object
var age = sj.Get("user:age"); // Returns strongly-typed int
// Smart type conversions
sj.Set("stringNumber", "42");
var number = sj.Get("stringNumber"); // Returns 42 (int)
sj.Set("numberString", 123);
var text = sj.Get("numberString"); // Returns "123" (string)
// Complex type handling
var user = sj.Get("user"); // Deserializes to custom type
```
**Type Conversion Features**:
- String β Number conversions (int, long, double, decimal, float)
- JsonElement handling for complex deserialization
- Automatic type detection and conversion
- Returns `default(T)` for failed conversions
#### HasPath(string path)
Safely checks if a path exists:
```csharp
bool exists = sj.HasPath("user:name"); // true/false
bool invalid = sj.HasPath("invalid[]path"); // false (doesn't throw)
```
#### Remove(string path)
Removes values with intelligent array handling:
```csharp
bool removed = sj.Remove("user:age"); // Removes property
bool arrayRemoved = sj.Remove("items[1]"); // Removes and shifts array elements
```
#### ListPaths()
Discovers all paths and values in your structure:
```csharp
var paths = sj.ListPaths();
// Returns: Dictionary
// Example output:
// "user:name" -> "John"
// "user:addresses[0]:city" -> "Ankara"
// "user:addresses[1]:city" -> "Istanbul"
```
#### ToJson(JsonSerializerOptions? options = null)
Converts to JSON with flexible formatting:
```csharp
var prettyJson = sj.ToJson(); // Pretty-printed (default)
var compactJson = sj.ToJson(new JsonSerializerOptions {
WriteIndented = false
});
```
#### Clear()
Removes all data from the structure:
```csharp
sj.Clear(); // Structure becomes empty: {}
```
## π― Advanced Features
### Sparse Array Support
Automatically handles arrays with gaps:
```csharp
var sj = new StructuredJson();
sj.Set("items[0]", "first");
sj.Set("items[5]", "sixth"); // Automatically fills [1-4] with null
var json = sj.ToJson();
// Result: {"items": ["first", null, null, null, null, "sixth"]}
```
### Unicode and International Support
Full support for international characters:
```csharp
sj.Set("turkish", "TΓΌrkΓ§e karakterler: ΔΓΌΕΔ±ΓΆΓ§");
sj.Set("emoji", "π π π π»");
sj.Set("chinese", "δ½ ε₯½δΈη");
sj.Set("arabic", "Ω
Ψ±ΨΨ¨Ψ§ Ψ¨Ψ§ΩΨΉΨ§ΩΩ
");
// All perfectly preserved in JSON output
```
### Complex Object Handling
Works seamlessly with custom objects:
```csharp
public class Address
{
public string City { get; set; }
public string Country { get; set; }
public double[] Coordinates { get; set; }
}
var address = new Address
{
City = "Ankara",
Country = "Turkey",
Coordinates = new[] { 39.9334, 32.8597 }
};
sj.Set("user:address", address);
var retrievedAddress = sj.Get
("user:address");
```
### Performance Optimizations
Handles large-scale operations efficiently:
```csharp
// Efficient for large datasets
for (int i = 0; i < 10000; i++)
{
sj.Set($"data:items[{i}]:id", i);
sj.Set($"data:items[{i}]:value", $"Item {i}");
}
// Fast path-based lookups with O(1) dictionary access
var item5000 = sj.Get("data:items[5000]:value");
```
## π Real-World Examples
### User Profile Management
```csharp
var profile = new StructuredJson();
// Basic info
profile.Set("user:id", 12345);
profile.Set("user:name", "John Doe");
profile.Set("user:email", "john@example.com");
profile.Set("user:isVerified", true);
// Multiple addresses
profile.Set("user:addresses[0]:type", "home");
profile.Set("user:addresses[0]:street", "123 Main St");
profile.Set("user:addresses[0]:city", "Ankara");
profile.Set("user:addresses[0]:country", "Turkey");
profile.Set("user:addresses[1]:type", "work");
profile.Set("user:addresses[1]:street", "456 Business Ave");
profile.Set("user:addresses[1]:city", "Istanbul");
profile.Set("user:addresses[1]:country", "Turkey");
// Preferences
profile.Set("user:preferences:theme", "dark");
profile.Set("user:preferences:language", "tr-TR");
profile.Set("user:preferences:notifications:email", true);
profile.Set("user:preferences:notifications:sms", false);
// Access data
var homeAddress = profile.Get("user:addresses[0]:city"); // "Ankara"
var emailNotifications = profile.Get("user:preferences:notifications:email"); // true
```
### Configuration Management
```csharp
var config = new StructuredJson();
// Database settings
config.Set("database:host", "localhost");
config.Set("database:port", 5432);
config.Set("database:name", "myapp");
config.Set("database:ssl", true);
// API endpoints
config.Set("api:endpoints[0]:name", "users");
config.Set("api:endpoints[0]:url", "/api/v1/users");
config.Set("api:endpoints[0]:methods[0]", "GET");
config.Set("api:endpoints[0]:methods[1]", "POST");
config.Set("api:endpoints[1]:name", "products");
config.Set("api:endpoints[1]:url", "/api/v1/products");
config.Set("api:endpoints[1]:methods[0]", "GET");
// Feature flags
config.Set("features:newDashboard", true);
config.Set("features:betaFeatures", false);
config.Set("features:maintenanceMode", false);
// Export to configuration file
File.WriteAllText("appsettings.json", config.ToJson());
```
### E-commerce Product Catalog
```csharp
var catalog = new StructuredJson();
// Product 1
catalog.Set("products[0]:id", "P001");
catalog.Set("products[0]:name", "Laptop");
catalog.Set("products[0]:price", 999.99m);
catalog.Set("products[0]:currency", "USD");
catalog.Set("products[0]:inStock", true);
catalog.Set("products[0]:specifications:cpu", "Intel i7");
catalog.Set("products[0]:specifications:ram", "16GB");
catalog.Set("products[0]:specifications:storage", "512GB SSD");
catalog.Set("products[0]:reviews[0]:rating", 5);
catalog.Set("products[0]:reviews[0]:comment", "Excellent laptop!");
catalog.Set("products[0]:reviews[1]:rating", 4);
catalog.Set("products[0]:reviews[1]:comment", "Good value for money");
// Product 2
catalog.Set("products[1]:id", "P002");
catalog.Set("products[1]:name", "Smartphone");
catalog.Set("products[1]:price", 599.99m);
catalog.Set("products[1]:inStock", false);
// Query products
var laptopPrice = catalog.Get("products[0]:price"); // 999.99
var laptopRating = catalog.Get("products[0]:reviews[0]:rating"); // 5
var phoneInStock = catalog.Get("products[1]:inStock"); // false
```
## π οΈ Error Handling
StructuredJson provides comprehensive error handling:
```csharp
try
{
var sj = new StructuredJson();
// These will throw ArgumentException with descriptive messages:
sj.Set("", "value"); // Empty path
sj.Set("items[]", "value"); // Empty array index
sj.Set("items[abc]", "value"); // Invalid array index
sj.Set("items[-1]", "value"); // Negative array index
}
catch (ArgumentException ex)
{
Console.WriteLine($"Path error: {ex.Message}");
}
try
{
// Invalid JSON in constructor
var sj = new StructuredJson("{invalid json}");
}
catch (ArgumentException ex)
{
Console.WriteLine($"JSON parsing error: {ex.Message}");
}
```
## π Path Discovery and Debugging
Easily explore your JSON structure:
```csharp
var sj = new StructuredJson();
sj.Set("user:name", "John");
sj.Set("user:addresses[0]:city", "Ankara");
sj.Set("user:addresses[1]:city", "Istanbul");
sj.Set("settings:theme", "dark");
// List all paths
var paths = sj.ListPaths();
foreach (var kvp in paths)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// Output:
// user:name: John
// user:addresses[0]:city: Ankara
// user:addresses[1]:city: Istanbul
// settings:theme: dark
// Check if specific paths exist
bool hasUserName = sj.HasPath("user:name"); // true
bool hasUserAge = sj.HasPath("user:age"); // false
bool hasFirstAddress = sj.HasPath("user:addresses[0]"); // true
```
## ποΈ Architecture and Performance
- **Underlying Structure**: `Dictionary` for O(1) key lookups
- **Serialization**: `System.Text.Json` for modern, high-performance JSON handling
- **Memory Efficient**: Sparse arrays don't allocate unnecessary memory
- **Path Parsing**: Optimized regex-based path parsing with caching
- **Type Conversion**: Lazy evaluation with intelligent fallback strategies
- **Cross-platform**: Full compatibility across Windows, macOS, and Linux
## π§ͺ Framework Compatibility
- **.NET Standard 2.0**: Maximum compatibility with all .NET implementations
- **.NET 8.0**: Latest performance optimizations and nullable reference types
- **.NET 9.0**: Cutting-edge features and improvements
- **Cross-platform**: Windows, macOS, Linux support
- **Legacy Support**: Works with .NET Framework 4.6.1+
## π License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## π€ Contributing
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
## π Changelog
See [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes and version history.
## π Issues and Support
- **Bug Reports**: [GitHub Issues](https://github.com/adomorn/StructuredJson/issues)
- **Feature Requests**: [GitHub Discussions](https://github.com/adomorn/StructuredJson/discussions)
- **Documentation**: This README and XML documentation in the code
---
**Made with β€οΈ for the .NET**