{"id":29483743,"url":"https://github.com/adomorn/structuredjson","last_synced_at":"2025-10-30T01:20:55.901Z","repository":{"id":298260541,"uuid":"995931167","full_name":"adomorn/StructuredJson","owner":"adomorn","description":"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.","archived":false,"fork":false,"pushed_at":"2025-06-29T14:23:28.000Z","size":111,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"development","last_synced_at":"2025-07-05T07:49:02.799Z","etag":null,"topics":["class-library","dotnet","json","nuget-package"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adomorn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-04T08:02:38.000Z","updated_at":"2025-06-29T14:23:32.000Z","dependencies_parsed_at":"2025-06-10T07:46:02.838Z","dependency_job_id":"05ffba42-712d-4f4f-a8d5-0eb705db2a7d","html_url":"https://github.com/adomorn/StructuredJson","commit_stats":null,"previous_names":["adomorn/structuredjson"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/adomorn/StructuredJson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adomorn%2FStructuredJson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adomorn%2FStructuredJson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adomorn%2FStructuredJson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adomorn%2FStructuredJson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adomorn","download_url":"https://codeload.github.com/adomorn/StructuredJson/tar.gz/refs/heads/development","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adomorn%2FStructuredJson/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265401323,"owners_count":23758987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class-library","dotnet","json","nuget-package"],"created_at":"2025-07-15T04:01:37.454Z","updated_at":"2025-10-30T01:20:55.894Z","avatar_url":"https://github.com/adomorn.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StructuredJson\n\n[![NuGet Version](https://img.shields.io/nuget/v/StructuredJson.svg)](https://www.nuget.org/packages/StructuredJson/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![.NET](https://img.shields.io/badge/.NET-Standard%202.0%20%7C%208.0%20%7C%209.0-purple.svg)](https://dotnet.microsoft.com/)\n[![Release NuGet Package](https://github.com/adomorn/StructuredJson/actions/workflows/release.yml/badge.svg)](https://github.com/adomorn/StructuredJson/actions/workflows/release.yml)\n[![SonarCloud analysis](https://github.com/adomorn/StructuredJson/actions/workflows/sonarcloud.yml/badge.svg)](https://github.com/adomorn/StructuredJson/actions/workflows/sonarcloud.yml)\n\nA powerful .NET library for creating, reading, and updating JSON objects using a path-based API. Built with `Dictionary\u003cstring, object?\u003e` as the underlying data structure and `System.Text.Json` for modern, high-performance serialization.\n\n## ✨ Features\n\n- **🔗 Path-based API**: Intuitive path syntax for navigating and manipulating JSON structures\n- **🌐 Cross-platform**: Full compatibility with .NET Standard 2.0, .NET 8, and .NET 9\n- **⚡ High Performance**: Uses `System.Text.Json` for optimal serialization performance\n- **🔄 Smart Type Conversion**: Intelligent conversion between strings, numbers, and complex types\n- **📋 Full CRUD Operations**: Complete Create, Read, Update, Delete capabilities with robust error handling\n- **🎯 Sparse Array Support**: Efficient handling of arrays with automatic null-filling for gaps\n- **🌍 Unicode Ready**: Full support for international characters, emojis, and special symbols\n- **📊 Path Validation**: Comprehensive validation with meaningful error messages\n- **🔍 Path Discovery**: List all paths and values in your JSON structure\n- **📖 Well Documented**: Complete XML documentation and extensive unit test coverage\n\n## 📦 Installation\n\nInstall via NuGet Package Manager:\n\n```bash\ndotnet add package StructuredJson\n```\n\nOr via Package Manager Console:\n\n```powershell\nInstall-Package StructuredJson\n```\n\nOr via PackageReference in your `.csproj`:\n\n```xml\n\u003cPackageReference Include=\"StructuredJson\" Version=\"1.0.0\" /\u003e\n```\n\n## 🚀 Quick Start\n\n```csharp\nusing StructuredJson;\n\n// Create a new instance\nvar sj = new StructuredJson();\n\n// Set values using intuitive path syntax\nsj.Set(\"user:name\", \"John Doe\");\nsj.Set(\"user:age\", 30);\nsj.Set(\"user:isActive\", true);\nsj.Set(\"user:addresses[0]:city\", \"Ankara\");\nsj.Set(\"user:addresses[0]:country\", \"Turkey\");\nsj.Set(\"user:addresses[1]:city\", \"Istanbul\");\n\n// Get values with automatic type conversion\nvar name = sj.Get(\"user:name\");                    // \"John Doe\"\nvar age = sj.Get\u003cint\u003e(\"user:age\");                 // 30\nvar isActive = sj.Get\u003cbool\u003e(\"user:isActive\");      // true\nvar city = sj.Get(\"user:addresses[0]:city\");       // \"Ankara\"\n\n// Convert to beautifully formatted JSON\nvar json = sj.ToJson();\nConsole.WriteLine(json);\n\n// List all paths and values\nvar paths = sj.ListPaths();\nforeach (var kvp in paths)\n{\n    Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n}\n```\n\n## 📍 Path Syntax\n\nStructuredJson uses an intuitive and powerful path syntax with comprehensive validation:\n\n### Object Properties\nUse `:` to navigate object properties:\n```csharp\nsj.Set(\"user:name\", \"John\");                    // user.name\nsj.Set(\"config:database:host\", \"localhost\");    // config.database.host\nsj.Set(\"app:settings:theme\", \"dark\");           // app.settings.theme\n```\n\n### Array Elements\nUse `[index]` to access array elements:\n```csharp\nsj.Set(\"users[0]\", \"John\");                     // users[0]\nsj.Set(\"items[2]:name\", \"Product\");             // items[2].name\nsj.Set(\"data[5]:values[3]\", 42);                // data[5].values[3]\n```\n\n### Complex Nested Paths\nCombine objects and arrays seamlessly:\n```csharp\nsj.Set(\"user:addresses[0]:coordinates:lat\", 39.9334);\nsj.Set(\"products[1]:reviews[0]:rating\", 5);\nsj.Set(\"config:servers[2]:endpoints[0]:url\", \"https://api.example.com\");\n```\n\n### Path Validation\nThe library provides comprehensive path validation:\n- ✅ `\"user:name\"` - Valid object property\n- ✅ `\"items[0]\"` - Valid array element\n- ✅ `\"data:list[5]:value\"` - Valid nested path\n- ❌ `\"items[]\"` - Invalid: empty array index\n- ❌ `\"items[-1]\"` - Invalid: negative index\n- ❌ `\"items[abc]\"` - Invalid: non-numeric index\n\n## 🔧 API Reference\n\n### Constructors\n\n```csharp\n// Create empty structure\nvar sj = new StructuredJson();\n\n// Create from JSON string (with comprehensive validation)\nvar sj = new StructuredJson(jsonString);\n```\n\n### Core Methods\n\n#### Set(string path, object? value)\nSets a value at the specified path, creating nested structures automatically:\n\n```csharp\nsj.Set(\"user:name\", \"John\");\nsj.Set(\"user:addresses[0]:city\", \"Ankara\");\nsj.Set(\"items[5]\", \"value\");  // Creates sparse array with nulls at 0-4\n\n// Supports all data types\nsj.Set(\"numbers:int\", 42);\nsj.Set(\"numbers:decimal\", 123.45m);\nsj.Set(\"flags:isActive\", true);\nsj.Set(\"data:nullValue\", null);\nsj.Set(\"text:unicode\", \"🚀 Türkçe 你好\");\n```\n\n**Throws**: `ArgumentException` for invalid paths\n\n#### Get(string path) / Get\u003cT\u003e(string path)\nRetrieves values with intelligent type conversion:\n\n```csharp\n// Basic retrieval\nvar name = sj.Get(\"user:name\");          // Returns object\nvar age = sj.Get\u003cint\u003e(\"user:age\");       // Returns strongly-typed int\n\n// Smart type conversions\nsj.Set(\"stringNumber\", \"42\");\nvar number = sj.Get\u003cint\u003e(\"stringNumber\");     // Returns 42 (int)\n\nsj.Set(\"numberString\", 123);\nvar text = sj.Get\u003cstring\u003e(\"numberString\");    // Returns \"123\" (string)\n\n// Complex type handling\nvar user = sj.Get\u003cUserModel\u003e(\"user\");         // Deserializes to custom type\n```\n\n**Type Conversion Features**:\n- String ↔ Number conversions (int, long, double, decimal, float)\n- JsonElement handling for complex deserialization\n- Automatic type detection and conversion\n- Returns `default(T)` for failed conversions\n\n#### HasPath(string path)\nSafely checks if a path exists:\n\n```csharp\nbool exists = sj.HasPath(\"user:name\");        // true/false\nbool invalid = sj.HasPath(\"invalid[]path\");   // false (doesn't throw)\n```\n\n#### Remove(string path)\nRemoves values with intelligent array handling:\n\n```csharp\nbool removed = sj.Remove(\"user:age\");         // Removes property\nbool arrayRemoved = sj.Remove(\"items[1]\");    // Removes and shifts array elements\n```\n\n#### ListPaths()\nDiscovers all paths and values in your structure:\n\n```csharp\nvar paths = sj.ListPaths();\n// Returns: Dictionary\u003cstring, object?\u003e\n// Example output:\n// \"user:name\" -\u003e \"John\"\n// \"user:addresses[0]:city\" -\u003e \"Ankara\"\n// \"user:addresses[1]:city\" -\u003e \"Istanbul\"\n```\n\n#### ToJson(JsonSerializerOptions? options = null)\nConverts to JSON with flexible formatting:\n\n```csharp\nvar prettyJson = sj.ToJson();                 // Pretty-printed (default)\nvar compactJson = sj.ToJson(new JsonSerializerOptions { \n    WriteIndented = false \n});\n```\n\n#### Clear()\nRemoves all data from the structure:\n\n```csharp\nsj.Clear();  // Structure becomes empty: {}\n```\n\n## 🎯 Advanced Features\n\n### Sparse Array Support\nAutomatically handles arrays with gaps:\n\n```csharp\nvar sj = new StructuredJson();\nsj.Set(\"items[0]\", \"first\");\nsj.Set(\"items[5]\", \"sixth\");     // Automatically fills [1-4] with null\n\nvar json = sj.ToJson();\n// Result: {\"items\": [\"first\", null, null, null, null, \"sixth\"]}\n```\n\n### Unicode and International Support\nFull support for international characters:\n\n```csharp\nsj.Set(\"turkish\", \"Türkçe karakterler: ğüşıöç\");\nsj.Set(\"emoji\", \"🚀 🎉 🌟 💻\");\nsj.Set(\"chinese\", \"你好世界\");\nsj.Set(\"arabic\", \"مرحبا بالعالم\");\n\n// All perfectly preserved in JSON output\n```\n\n### Complex Object Handling\nWorks seamlessly with custom objects:\n\n```csharp\npublic class Address\n{\n    public string City { get; set; }\n    public string Country { get; set; }\n    public double[] Coordinates { get; set; }\n}\n\nvar address = new Address \n{ \n    City = \"Ankara\", \n    Country = \"Turkey\", \n    Coordinates = new[] { 39.9334, 32.8597 } \n};\n\nsj.Set(\"user:address\", address);\nvar retrievedAddress = sj.Get\u003cAddress\u003e(\"user:address\");\n```\n\n### Performance Optimizations\nHandles large-scale operations efficiently:\n\n```csharp\n// Efficient for large datasets\nfor (int i = 0; i \u003c 10000; i++)\n{\n    sj.Set($\"data:items[{i}]:id\", i);\n    sj.Set($\"data:items[{i}]:value\", $\"Item {i}\");\n}\n\n// Fast path-based lookups with O(1) dictionary access\nvar item5000 = sj.Get(\"data:items[5000]:value\");\n```\n\n## 📊 Real-World Examples\n\n### User Profile Management\n```csharp\nvar profile = new StructuredJson();\n\n// Basic info\nprofile.Set(\"user:id\", 12345);\nprofile.Set(\"user:name\", \"John Doe\");\nprofile.Set(\"user:email\", \"john@example.com\");\nprofile.Set(\"user:isVerified\", true);\n\n// Multiple addresses\nprofile.Set(\"user:addresses[0]:type\", \"home\");\nprofile.Set(\"user:addresses[0]:street\", \"123 Main St\");\nprofile.Set(\"user:addresses[0]:city\", \"Ankara\");\nprofile.Set(\"user:addresses[0]:country\", \"Turkey\");\n\nprofile.Set(\"user:addresses[1]:type\", \"work\"); \nprofile.Set(\"user:addresses[1]:street\", \"456 Business Ave\");\nprofile.Set(\"user:addresses[1]:city\", \"Istanbul\");\nprofile.Set(\"user:addresses[1]:country\", \"Turkey\");\n\n// Preferences\nprofile.Set(\"user:preferences:theme\", \"dark\");\nprofile.Set(\"user:preferences:language\", \"tr-TR\");\nprofile.Set(\"user:preferences:notifications:email\", true);\nprofile.Set(\"user:preferences:notifications:sms\", false);\n\n// Access data\nvar homeAddress = profile.Get(\"user:addresses[0]:city\");  // \"Ankara\"\nvar emailNotifications = profile.Get\u003cbool\u003e(\"user:preferences:notifications:email\");  // true\n```\n\n### Configuration Management\n```csharp\nvar config = new StructuredJson();\n\n// Database settings\nconfig.Set(\"database:host\", \"localhost\");\nconfig.Set(\"database:port\", 5432);\nconfig.Set(\"database:name\", \"myapp\");\nconfig.Set(\"database:ssl\", true);\n\n// API endpoints\nconfig.Set(\"api:endpoints[0]:name\", \"users\");\nconfig.Set(\"api:endpoints[0]:url\", \"/api/v1/users\");\nconfig.Set(\"api:endpoints[0]:methods[0]\", \"GET\");\nconfig.Set(\"api:endpoints[0]:methods[1]\", \"POST\");\n\nconfig.Set(\"api:endpoints[1]:name\", \"products\");\nconfig.Set(\"api:endpoints[1]:url\", \"/api/v1/products\");\nconfig.Set(\"api:endpoints[1]:methods[0]\", \"GET\");\n\n// Feature flags\nconfig.Set(\"features:newDashboard\", true);\nconfig.Set(\"features:betaFeatures\", false);\nconfig.Set(\"features:maintenanceMode\", false);\n\n// Export to configuration file\nFile.WriteAllText(\"appsettings.json\", config.ToJson());\n```\n\n### E-commerce Product Catalog\n```csharp\nvar catalog = new StructuredJson();\n\n// Product 1\ncatalog.Set(\"products[0]:id\", \"P001\");\ncatalog.Set(\"products[0]:name\", \"Laptop\");\ncatalog.Set(\"products[0]:price\", 999.99m);\ncatalog.Set(\"products[0]:currency\", \"USD\");\ncatalog.Set(\"products[0]:inStock\", true);\n\ncatalog.Set(\"products[0]:specifications:cpu\", \"Intel i7\");\ncatalog.Set(\"products[0]:specifications:ram\", \"16GB\");\ncatalog.Set(\"products[0]:specifications:storage\", \"512GB SSD\");\n\ncatalog.Set(\"products[0]:reviews[0]:rating\", 5);\ncatalog.Set(\"products[0]:reviews[0]:comment\", \"Excellent laptop!\");\ncatalog.Set(\"products[0]:reviews[1]:rating\", 4);\ncatalog.Set(\"products[0]:reviews[1]:comment\", \"Good value for money\");\n\n// Product 2\ncatalog.Set(\"products[1]:id\", \"P002\");\ncatalog.Set(\"products[1]:name\", \"Smartphone\");\ncatalog.Set(\"products[1]:price\", 599.99m);\ncatalog.Set(\"products[1]:inStock\", false);\n\n// Query products\nvar laptopPrice = catalog.Get\u003cdecimal\u003e(\"products[0]:price\");  // 999.99\nvar laptopRating = catalog.Get\u003cint\u003e(\"products[0]:reviews[0]:rating\");  // 5\nvar phoneInStock = catalog.Get\u003cbool\u003e(\"products[1]:inStock\");  // false\n```\n\n## 🛠️ Error Handling\n\nStructuredJson provides comprehensive error handling:\n\n```csharp\ntry\n{\n    var sj = new StructuredJson();\n    \n    // These will throw ArgumentException with descriptive messages:\n    sj.Set(\"\", \"value\");           // Empty path\n    sj.Set(\"items[]\", \"value\");    // Empty array index\n    sj.Set(\"items[abc]\", \"value\"); // Invalid array index\n    sj.Set(\"items[-1]\", \"value\");  // Negative array index\n}\ncatch (ArgumentException ex)\n{\n    Console.WriteLine($\"Path error: {ex.Message}\");\n}\n\ntry\n{\n    // Invalid JSON in constructor\n    var sj = new StructuredJson(\"{invalid json}\");\n}\ncatch (ArgumentException ex)\n{\n    Console.WriteLine($\"JSON parsing error: {ex.Message}\");\n}\n```\n\n## 🔍 Path Discovery and Debugging\n\nEasily explore your JSON structure:\n\n```csharp\nvar sj = new StructuredJson();\nsj.Set(\"user:name\", \"John\");\nsj.Set(\"user:addresses[0]:city\", \"Ankara\");\nsj.Set(\"user:addresses[1]:city\", \"Istanbul\");\nsj.Set(\"settings:theme\", \"dark\");\n\n// List all paths\nvar paths = sj.ListPaths();\nforeach (var kvp in paths)\n{\n    Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n}\n\n// Output:\n// user:name: John\n// user:addresses[0]:city: Ankara\n// user:addresses[1]:city: Istanbul\n// settings:theme: dark\n\n// Check if specific paths exist\nbool hasUserName = sj.HasPath(\"user:name\");        // true\nbool hasUserAge = sj.HasPath(\"user:age\");          // false\nbool hasFirstAddress = sj.HasPath(\"user:addresses[0]\");  // true\n```\n\n## 🏗️ Architecture and Performance\n\n- **Underlying Structure**: `Dictionary\u003cstring, object?\u003e` for O(1) key lookups\n- **Serialization**: `System.Text.Json` for modern, high-performance JSON handling\n- **Memory Efficient**: Sparse arrays don't allocate unnecessary memory\n- **Path Parsing**: Optimized regex-based path parsing with caching\n- **Type Conversion**: Lazy evaluation with intelligent fallback strategies\n- **Cross-platform**: Full compatibility across Windows, macOS, and Linux\n\n## 🧪 Framework Compatibility\n\n- **.NET Standard 2.0**: Maximum compatibility with all .NET implementations\n- **.NET 8.0**: Latest performance optimizations and nullable reference types\n- **.NET 9.0**: Cutting-edge features and improvements\n- **Cross-platform**: Windows, macOS, Linux support\n- **Legacy Support**: Works with .NET Framework 4.6.1+\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🤝 Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.\n\n## 📋 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes and version history.\n\n## 🐛 Issues and Support\n\n- **Bug Reports**: [GitHub Issues](https://github.com/adomorn/StructuredJson/issues)\n- **Feature Requests**: [GitHub Discussions](https://github.com/adomorn/StructuredJson/discussions)\n- **Documentation**: This README and XML documentation in the code\n\n---\n\n**Made with ❤️ for the .NET** \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadomorn%2Fstructuredjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadomorn%2Fstructuredjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadomorn%2Fstructuredjson/lists"}