{"id":37315035,"url":"https://github.com/dborgards/eds-dcf-net","last_synced_at":"2026-05-06T06:06:28.887Z","repository":{"id":329003708,"uuid":"1117723120","full_name":"dborgards/eds-dcf-net","owner":"dborgards","description":"C# .NET CANopen library for EDS, DCF, CPJ, XDD and XDC (CiA 306 / CiA 311)","archived":false,"fork":false,"pushed_at":"2026-05-02T09:35:23.000Z","size":1089,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-02T09:38:10.252Z","etag":null,"topics":["canopen","cia","csharp","csharp-library","dcf","dotnet","dotnet-core","eds","fieldbus","industrial-automation","xdc","xdd"],"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/dborgards.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"dborgards","buy_me_a_coffee":"dborgards"}},"created_at":"2025-12-16T18:10:08.000Z","updated_at":"2026-05-02T09:21:55.000Z","dependencies_parsed_at":"2026-02-26T11:07:50.078Z","dependency_job_id":null,"html_url":"https://github.com/dborgards/eds-dcf-net","commit_stats":null,"previous_names":["dborgards/eds-dcf-net"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/dborgards/eds-dcf-net","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dborgards%2Feds-dcf-net","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dborgards%2Feds-dcf-net/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dborgards%2Feds-dcf-net/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dborgards%2Feds-dcf-net/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dborgards","download_url":"https://codeload.github.com/dborgards/eds-dcf-net/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dborgards%2Feds-dcf-net/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32679446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["canopen","cia","csharp","csharp-library","dcf","dotnet","dotnet-core","eds","fieldbus","industrial-automation","xdc","xdd"],"created_at":"2026-01-16T03:08:27.331Z","updated_at":"2026-05-06T06:06:28.856Z","avatar_url":"https://github.com/dborgards.png","language":"C#","funding_links":["https://github.com/sponsors/dborgards","https://buymeacoffee.com/dborgards"],"categories":[],"sub_categories":[],"readme":"# EdsDcfNet\n\n[![Build Status](https://github.com/dborgards/eds-dcf-net/actions/workflows/build.yml/badge.svg)](https://github.com/dborgards/eds-dcf-net/actions/workflows/build.yml)\n[![Semantic Release](https://img.shields.io/badge/semantic--release-conventionalcommits-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)\n[![NuGet Version](https://img.shields.io/nuget/v/EdsDcfNet)](https://www.nuget.org/packages/EdsDcfNet)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/EdsDcfNet)](https://www.nuget.org/packages/EdsDcfNet)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![codecov](https://codecov.io/gh/dborgards/eds-dcf-net/branch/main/graph/badge.svg)](https://codecov.io/gh/dborgards/eds-dcf-net)\n\nA comprehensive, easy-to-use C# .NET library for CANopen file formats:\nCiA DS 306 (EDS, DCF, CPJ) and CiA 311 (XDD, XDC).\n\n## Features\n\n✨ **Simple API** - Intuitive, fluent API style for quick integration\n\n📖 **Read \u0026 Write EDS** - Parse and generate Electronic Data Sheets\n\n📝 **Read \u0026 Write DCF** - Process and create Device Configuration Files\n\n🌐 **Read \u0026 Write CPJ** - Parse and create Nodelist Project files (CiA 306-3 network topologies)\n\n🧩 **Read \u0026 Write XDD/XDC** - Parse and generate CiA 311 XML device descriptions/configurations\n\n🔄 **EDS to DCF Conversion** - Easy conversion with configuration parameters\n\n🎯 **Type-Safe** - Fully typed models for all CANopen objects\n\n📦 **Modular** - Support for modular devices (bus couplers + modules)\n\n✅ **CiA DS 306 v1.4 / CiA 311 v1.1 Compliant** - Implemented according to official specification\n\n## Quick Start\n\n### Reading an EDS File\n\n```csharp\nusing EdsDcfNet;\n\n// Read EDS file\nvar eds = CanOpenFile.ReadEds(\"device.eds\");\n\n// Display device information\nConsole.WriteLine($\"Device: {eds.DeviceInfo.ProductName}\");\nConsole.WriteLine($\"Vendor: {eds.DeviceInfo.VendorName}\");\nConsole.WriteLine($\"Product Number: 0x{eds.DeviceInfo.ProductNumber:X}\");\n```\n\n### Writing an EDS File\n\n```csharp\nusing EdsDcfNet;\n\nvar eds = CanOpenFile.ReadEds(\"device.eds\");\neds.FileInfo.FileRevision++;\nCanOpenFile.WriteEds(eds, \"device_updated.eds\");\n```\n\n### Async File I/O (`async`/`await`)\n\n```csharp\nusing EdsDcfNet;\nusing System.Threading;\n\nusing var cts = new CancellationTokenSource();\n\nvar eds = await CanOpenFile.ReadEdsAsync(\"device.eds\", cts.Token);\neds.FileInfo.FileRevision++;\nawait CanOpenFile.WriteEdsAsync(eds, \"device_updated.eds\", cts.Token);\n```\n\n### Stream-based I/O\n\n```csharp\nusing EdsDcfNet;\nusing System.IO;\n\nusing var stream = File.OpenRead(\"device.eds\");\nvar eds = CanOpenFile.ReadEds(stream);\n\nusing var outStream = new MemoryStream();\nCanOpenFile.WriteEds(eds, outStream);\n```\n\n\u003e Stream ownership: stream overloads do **not** dispose input/output streams.  \n\u003e The caller remains responsible for stream lifetime.\n\n## Output Encoding Policy\n\nAll writer APIs that persist text (`WriteEds*`, `WriteDcf*`, `WriteCpj*`, `WriteXdd*`, `WriteXdc*`)\nwrite **UTF-8 without BOM** by default for file and stream output.\n\nThis is an intentional interoperability choice:\n- CiA DS 306 is historically ASCII-oriented.\n- UTF-8 keeps full ASCII compatibility for 7-bit content.\n- UTF-8 also preserves non-ASCII characters in names/comments instead of replacing them.\n\n### Guidance for strict ASCII toolchains\n\nIf a downstream tool only accepts strict ASCII, keep model text in 7-bit ASCII characters,\nor transcode explicitly to strict ASCII at your boundary and fail fast on non-ASCII content.\n\n```csharp\nusing EdsDcfNet;\nusing System.IO;\nusing System.Text;\n\nvar asciiStrict = Encoding.GetEncoding(\n    \"us-ascii\",\n    EncoderFallback.ExceptionFallback,\n    DecoderFallback.ExceptionFallback);\n\nvar dcf = CanOpenFile.ReadDcf(\"device.dcf\");\nvar text = CanOpenFile.WriteDcfToString(dcf);\nFile.WriteAllText(\"device_ascii.dcf\", text, asciiStrict);\n```\n\n### Reading an XDD File (CiA 311 XML)\n\n```csharp\nusing EdsDcfNet;\n\n// Read XDD file\nvar xdd = CanOpenFile.ReadXdd(\"device.xdd\");\n\nConsole.WriteLine($\"Device: {xdd.DeviceInfo.ProductName}\");\nConsole.WriteLine($\"Vendor: {xdd.DeviceInfo.VendorName}\");\n```\n\n### Reading a DCF File\n\n```csharp\nusing EdsDcfNet;\n\n// Read DCF file\nvar dcf = CanOpenFile.ReadDcf(\"configured_device.dcf\");\n\nConsole.WriteLine($\"Node ID: {dcf.DeviceCommissioning.NodeId}\");\nConsole.WriteLine($\"Baudrate: {dcf.DeviceCommissioning.Baudrate} kbit/s\");\n```\n\n### Reading an XDC File (CiA 311 XML)\n\n```csharp\nusing EdsDcfNet;\n\n// Read XDC file\nvar xdc = CanOpenFile.ReadXdc(\"configured_device.xdc\");\n\nConsole.WriteLine($\"Node ID: {xdc.DeviceCommissioning.NodeId}\");\nConsole.WriteLine($\"Baudrate: {xdc.DeviceCommissioning.Baudrate} kbit/s\");\n```\n\n### Working with ApplicationProcess (CiA 311 §6.4.5)\n\nXDD/XDC files may include an `ApplicationProcess` element describing device parameters\nat the application level. The typed model gives full programmatic access to all\nsub-constructs.\n\n```csharp\nusing EdsDcfNet;\n\nvar xdd = CanOpenFile.ReadXdd(\"device.xdd\");\n\nif (xdd.ApplicationProcess is { } ap)\n{\n    // Iterate parameters\n    foreach (var param in ap.ParameterList)\n    {\n        var displayName = param.LabelGroup.GetDisplayName() ?? param.UniqueId;\n        Console.WriteLine($\"Parameter: {displayName}\");\n    }\n\n    // Inspect data type definitions\n    if (ap.DataTypeList is { } dtl)\n    {\n        foreach (var enumType in dtl.Enums)\n            Console.WriteLine($\"Enum type: {enumType.Name}\");\n    }\n}\n```\n\n### Converting EDS to DCF\n\n```csharp\nusing EdsDcfNet;\n\n// Read EDS\nvar eds = CanOpenFile.ReadEds(\"device.eds\");\n\n// Convert to DCF with node ID and baudrate\nvar dcf = CanOpenFile.EdsToDcf(eds, nodeId: 2, baudrate: 500, nodeName: \"MyDevice\");\n\n// Save DCF\nCanOpenFile.WriteDcf(dcf, \"device_node2.dcf\");\n```\n\n### Validating models before write operations\n\nUse the validation API to detect invalid commissioning values and inconsistent\nobject-list definitions before serializing files.\n\n```csharp\nusing EdsDcfNet;\nusing EdsDcfNet.Validation;\n\nvar dcf = CanOpenFile.ReadDcf(\"configured_device.dcf\");\n\nIReadOnlyList\u003cValidationIssue\u003e issues = CanOpenFile.Validate(dcf);\nif (issues.Count \u003e 0)\n{\n    foreach (var issue in issues)\n        Console.WriteLine(issue);\n}\n```\n\n`CanOpenFile.Validate(...)` is the recommended entry point and routes to the\nfull model validator, returning path-based `ValidationIssue` entries.\nCurrent checks include:\n\n- commissioning constraints (Node-ID range `1..127` for commissioned nodes; `NodeId == 0` is accepted only when commissioning is omitted, baudrate range with `0` accepted for that omitted state, key string limits)\n- device info constraints (name/order-code length, granularity limit)\n- object dictionary consistency (list membership, duplicates, missing entries)\n- object-level constraints (object type validity, parameter-name length, SubNumber mismatch)\n\n### Working with Nodelist Projects (CPJ)\n\n```csharp\nusing EdsDcfNet;\nusing EdsDcfNet.Models;\n\n// Read a CPJ file describing the network topology\nvar cpj = CanOpenFile.ReadCpj(\"nodelist.cpj\");\n\nforeach (var network in cpj.Networks)\n{\n    Console.WriteLine($\"Network: {network.NetName}\");\n    foreach (var node in network.Nodes.Values)\n    {\n        Console.WriteLine($\"  Node {node.NodeId}: {node.Name} ({node.DcfFileName})\");\n    }\n}\n\n// Create a new CPJ\nvar project = new NodelistProject();\nproject.Networks.Add(new NetworkTopology\n{\n    NetName = \"Production Line 1\",\n    Nodes =\n    {\n        [2] = new NetworkNode { NodeId = 2, Present = true, Name = \"PLC\", DcfFileName = \"plc.dcf\" },\n        [3] = new NetworkNode { NodeId = 3, Present = true, Name = \"IO Module\", DcfFileName = \"io.dcf\" }\n    }\n});\nCanOpenFile.WriteCpj(project, \"network.cpj\");\n```\n\n### Working with Object Dictionary\n\n```csharp\nusing EdsDcfNet.Extensions;\n\nvar dcf = CanOpenFile.ReadDcf(\"device.dcf\");\n\n// Get object\nvar deviceType = dcf.ObjectDictionary.GetObject(0x1000);\n\n// Set value (returns true if object exists, false if not found)\nbool set = dcf.ObjectDictionary.SetParameterValue(0x1000, \"0x00000191\");\n\n// Browse PDO objects\nvar tpdos = dcf.ObjectDictionary.GetPdoCommunicationParameters(transmit: true);\n```\n\n## API Overview\n\n### Main Class: `CanOpenFile`\n\nWriter encoding note: all file/stream `Write*` APIs use UTF-8 without BOM.\n\n```csharp\n// Read EDS\nElectronicDataSheet ReadEds(string filePath)\nElectronicDataSheet ReadEds(string filePath, long maxInputSize)\nTask\u003cElectronicDataSheet\u003e ReadEdsAsync(string filePath, CancellationToken cancellationToken = default)\nTask\u003cElectronicDataSheet\u003e ReadEdsAsync(string filePath, long maxInputSize, CancellationToken cancellationToken = default)\nElectronicDataSheet ReadEdsFromString(string content)\nElectronicDataSheet ReadEdsFromString(string content, long maxInputSize)\nElectronicDataSheet ReadEds(Stream stream)\nElectronicDataSheet ReadEds(Stream stream, long maxInputSize)\nTask\u003cElectronicDataSheet\u003e ReadEdsAsync(Stream stream, CancellationToken cancellationToken = default)\nTask\u003cElectronicDataSheet\u003e ReadEdsAsync(Stream stream, long maxInputSize, CancellationToken cancellationToken = default)\n\n// Write EDS\nvoid WriteEds(ElectronicDataSheet eds, string filePath)\nvoid WriteEds(ElectronicDataSheet eds, Stream stream)\nTask WriteEdsAsync(ElectronicDataSheet eds, string filePath, CancellationToken cancellationToken = default)\nTask WriteEdsAsync(ElectronicDataSheet eds, Stream stream, CancellationToken cancellationToken = default)\nstring WriteEdsToString(ElectronicDataSheet eds)\n\n// Read DCF\nDeviceConfigurationFile ReadDcf(string filePath)\nDeviceConfigurationFile ReadDcf(string filePath, long maxInputSize)\nTask\u003cDeviceConfigurationFile\u003e ReadDcfAsync(string filePath, CancellationToken cancellationToken = default)\nTask\u003cDeviceConfigurationFile\u003e ReadDcfAsync(string filePath, long maxInputSize, CancellationToken cancellationToken = default)\nDeviceConfigurationFile ReadDcfFromString(string content)\nDeviceConfigurationFile ReadDcfFromString(string content, long maxInputSize)\nDeviceConfigurationFile ReadDcf(Stream stream)\nDeviceConfigurationFile ReadDcf(Stream stream, long maxInputSize)\nTask\u003cDeviceConfigurationFile\u003e ReadDcfAsync(Stream stream, CancellationToken cancellationToken = default)\nTask\u003cDeviceConfigurationFile\u003e ReadDcfAsync(Stream stream, long maxInputSize, CancellationToken cancellationToken = default)\n\n// Write DCF\nvoid WriteDcf(DeviceConfigurationFile dcf, string filePath)\nvoid WriteDcf(DeviceConfigurationFile dcf, Stream stream)\nTask WriteDcfAsync(DeviceConfigurationFile dcf, string filePath, CancellationToken cancellationToken = default)\nTask WriteDcfAsync(DeviceConfigurationFile dcf, Stream stream, CancellationToken cancellationToken = default)\nstring WriteDcfToString(DeviceConfigurationFile dcf)\n\n// Read CPJ (CiA 306-3 Nodelist Project)\nNodelistProject ReadCpj(string filePath)\nNodelistProject ReadCpj(string filePath, long maxInputSize)\nTask\u003cNodelistProject\u003e ReadCpjAsync(string filePath, CancellationToken cancellationToken = default)\nTask\u003cNodelistProject\u003e ReadCpjAsync(string filePath, long maxInputSize, CancellationToken cancellationToken = default)\nNodelistProject ReadCpjFromString(string content)\nNodelistProject ReadCpjFromString(string content, long maxInputSize)\nNodelistProject ReadCpj(Stream stream)\nNodelistProject ReadCpj(Stream stream, long maxInputSize)\nTask\u003cNodelistProject\u003e ReadCpjAsync(Stream stream, CancellationToken cancellationToken = default)\nTask\u003cNodelistProject\u003e ReadCpjAsync(Stream stream, long maxInputSize, CancellationToken cancellationToken = default)\n\n// Write CPJ\nvoid WriteCpj(NodelistProject cpj, string filePath)\nvoid WriteCpj(NodelistProject cpj, Stream stream)\nTask WriteCpjAsync(NodelistProject cpj, string filePath, CancellationToken cancellationToken = default)\nTask WriteCpjAsync(NodelistProject cpj, Stream stream, CancellationToken cancellationToken = default)\nstring WriteCpjToString(NodelistProject cpj)\n\n// Read XDD (CiA 311 XML Device Description)\nElectronicDataSheet ReadXdd(string filePath)\nElectronicDataSheet ReadXdd(string filePath, long maxInputSize)\nTask\u003cElectronicDataSheet\u003e ReadXddAsync(string filePath, CancellationToken cancellationToken = default)\nTask\u003cElectronicDataSheet\u003e ReadXddAsync(string filePath, long maxInputSize, CancellationToken cancellationToken = default)\nElectronicDataSheet ReadXddFromString(string content)\nElectronicDataSheet ReadXddFromString(string content, long maxInputSize)\nElectronicDataSheet ReadXdd(Stream stream)\nElectronicDataSheet ReadXdd(Stream stream, long maxInputSize)\nTask\u003cElectronicDataSheet\u003e ReadXddAsync(Stream stream, CancellationToken cancellationToken = default)\nTask\u003cElectronicDataSheet\u003e ReadXddAsync(Stream stream, long maxInputSize, CancellationToken cancellationToken = default)\n\n// Write XDD\nvoid WriteXdd(ElectronicDataSheet xdd, string filePath)\nvoid WriteXdd(ElectronicDataSheet xdd, Stream stream)\nTask WriteXddAsync(ElectronicDataSheet xdd, string filePath, CancellationToken cancellationToken = default)\nTask WriteXddAsync(ElectronicDataSheet xdd, Stream stream, CancellationToken cancellationToken = default)\nstring WriteXddToString(ElectronicDataSheet xdd)\n\n// Read XDC (CiA 311 XML Device Configuration)\nDeviceConfigurationFile ReadXdc(string filePath)\nDeviceConfigurationFile ReadXdc(string filePath, long maxInputSize)\nTask\u003cDeviceConfigurationFile\u003e ReadXdcAsync(string filePath, CancellationToken cancellationToken = default)\nTask\u003cDeviceConfigurationFile\u003e ReadXdcAsync(string filePath, long maxInputSize, CancellationToken cancellationToken = default)\nDeviceConfigurationFile ReadXdcFromString(string content)\nDeviceConfigurationFile ReadXdcFromString(string content, long maxInputSize)\nDeviceConfigurationFile ReadXdc(Stream stream)\nDeviceConfigurationFile ReadXdc(Stream stream, long maxInputSize)\nTask\u003cDeviceConfigurationFile\u003e ReadXdcAsync(Stream stream, CancellationToken cancellationToken = default)\nTask\u003cDeviceConfigurationFile\u003e ReadXdcAsync(Stream stream, long maxInputSize, CancellationToken cancellationToken = default)\n\n// Write XDC\nvoid WriteXdc(DeviceConfigurationFile xdc, string filePath)\nvoid WriteXdc(DeviceConfigurationFile xdc, Stream stream)\nTask WriteXdcAsync(DeviceConfigurationFile xdc, string filePath, CancellationToken cancellationToken = default)\nTask WriteXdcAsync(DeviceConfigurationFile xdc, Stream stream, CancellationToken cancellationToken = default)\nstring WriteXdcToString(DeviceConfigurationFile xdc)\n\n// Validate models\nIReadOnlyList\u003cValidationIssue\u003e Validate(ElectronicDataSheet eds)\nIReadOnlyList\u003cValidationIssue\u003e Validate(DeviceConfigurationFile dcf)\n\n// Convert EDS to DCF\nDeviceConfigurationFile EdsToDcf(ElectronicDataSheet eds, byte nodeId,\n                                  ushort baudrate = 250, string? nodeName = null)\n```\n\n### Input Size Limits and Tuning\n\nAll read APIs apply a safe default input-size limit of **10 MB**\n(`IniParser.DefaultMaxInputSize`) to reduce denial-of-service risk from\nunexpectedly large payloads.\n\nYou can override this limit per operation when you need to process larger files:\n\n```csharp\nvar xdd = CanOpenFile.ReadXdd(\"large-device.xdd\", maxInputSize: 50L * 1024 * 1024);\n```\n\nGuidance:\n- Keep the default whenever possible.\n- Increase limits only for trusted sources and known use cases.\n- Set the limit just high enough for your expected maximum file size.\n\n## Supported Features\n\n- ✅ Complete EDS parsing and writing\n- ✅ Complete DCF parsing and writing\n- ✅ CPJ nodelist project parsing and writing (CiA 306-3 network topologies)\n- ✅ XDD parsing and writing (CiA 311 XML device description)\n- ✅ XDC parsing and writing (CiA 311 XML device configuration)\n- ✅ All Object Types (NULL, DOMAIN, DEFTYPE, DEFSTRUCT, VAR, ARRAY, RECORD)\n- ✅ Sub-objects and sub-indexes\n- ✅ Compact Storage (CompactSubObj, CompactPDO)\n- ✅ Object Links\n- ✅ Modular device concept\n- ✅ Hexadecimal, decimal, and octal numbers\n- ✅ $NODEID formula evaluation (e.g., $NODEID+0x200)\n- ✅ CANopen Safety (EN 50325-5) - SRDOMapping, InvertedSRAD\n- ✅ Comments and additional sections\n\n## Error Handling\n\nWriter APIs expose format-specific exceptions with context:\n\n- `EdsWriter` / `CanOpenFile.WriteEds*`: `EdsWriteException`\n- `DcfWriter` / `CanOpenFile.WriteDcf*`: `DcfWriteException`\n- `CpjWriter` / `CanOpenFile.WriteCpj*`: `CpjWriteException`\n- `XddWriter` / `CanOpenFile.WriteXdd*`: `XddWriteException`\n- `XdcWriter` / `CanOpenFile.WriteXdc*`: `XdcWriteException`\n\nWhen a failure can be attributed to a concrete generated section/element,\nthe exception contains a `SectionName` value (for example `DeviceInfo`,\n`Topology`, `DeviceProfile`, or `deviceCommissioning`).\n\n## Examples\n\nComplete examples can be found in the `examples/EdsDcfNet.Examples` project.\n\n## Performance Benchmarks\n\nA dedicated BenchmarkDotNet project is available at:\n\n- `benchmarks/EdsDcfNet.Benchmarks`\n\nRun all benchmarks:\n\n```bash\ndotnet run -c Release -p benchmarks/EdsDcfNet.Benchmarks -- --filter \"*\"\n```\n\nBaseline scenario definitions and artifact locations are documented in:\n\n- `benchmarks/EdsDcfNet.Benchmarks/BASELINE.md`\n\n## Project Structure\n\n```\neds-dcf-net/\n├── src/\n│   └── EdsDcfNet/              # Main library\n│       ├── Models/             # Data models\n│       ├── Parsers/            # EDS/DCF/CPJ/XDD/XDC parsers\n│       ├── Writers/            # EDS/DCF/CPJ/XDD/XDC writers\n│       ├── Utilities/          # Helper classes\n│       ├── Exceptions/         # Custom exceptions\n│       └── Extensions/         # Extension methods\n├── benchmarks/\n│   └── EdsDcfNet.Benchmarks/   # BenchmarkDotNet throughput/memory benchmarks\n├── examples/\n│   └── EdsDcfNet.Examples/     # Example application\n└── docs/\n    ├── architecture/           # ARC42 software architecture\n    └── cia/                    # CiA DS 306 specification\n```\n\n## Requirements\n\n**For consuming the NuGet package:**\n\n- Any .NET implementation compatible with .NET Standard 2.0\n  (e.g., .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+, Unity, Xamarin)\n\n**For building this repository (library, tests, examples):**\n\n- .NET SDK 10.0 or higher\n- C# 13.0 (as provided by the .NET 10 SDK)\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file\n\n## Specification\n\nBased on:\n- **CiA DS 306 Version 1.4.0** (December 15, 2021)\n- **CiA 311** XML device description/configuration concepts (XDD/XDC)\n\n## Support\n\nFor questions or issues:\n- GitHub Issues: https://github.com/dborgards/eds-dcf-net/issues\n\n---\n\n**EdsDcfNet** - Professional CANopen EDS/DCF/CPJ/XDD/XDC processing in C# .NET\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdborgards%2Feds-dcf-net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdborgards%2Feds-dcf-net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdborgards%2Feds-dcf-net/lists"}