Edifact.Structure 1.0.0-preview.3

This is a prerelease version of Edifact.Structure.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Edifact.Structure --version 1.0.0-preview.3
                    
NuGet\Install-Package Edifact.Structure -Version 1.0.0-preview.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Edifact.Structure" Version="1.0.0-preview.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Edifact.Structure" Version="1.0.0-preview.3" />
                    
Directory.Packages.props
<PackageReference Include="Edifact.Structure" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Edifact.Structure --version 1.0.0-preview.3
                    
#r "nuget: Edifact.Structure, 1.0.0-preview.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Edifact.Structure@1.0.0-preview.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Edifact.Structure&version=1.0.0-preview.3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Edifact.Structure&version=1.0.0-preview.3&prerelease
                    
Install as a Cake Tool

Edifact.Structure

Matches a segment stream against a message's segment table, resolving segment group nesting and repetition into a message tree with every position accounted for.

This is the layer that turns a flat list of segments into a shape: which NAD is the buyer's, which PRI belongs to which line item, and which segment nothing in the definition could place. It does not check element contents, code values or the envelope — that is Edifact.Validation, which uses this. Reach for this package directly when you want the tree and not the verdict: a viewer, a mapper, an extractor walking to SG26[2]/SG30[1]/PRI.

Install

dotnet add package Edifact.Structure --prerelease

net8.0 and net10.0, no external dependencies.

You supply the directory

No directory data ships in this package. A compiled pack is a derivative of the UN Directory, and shipping one would make every consumer a redistributor of it. Download a release from UNECE and ingest it once:

dotnet tool install --global Edifact.Cli --prerelease
edifact ingest ~/Downloads/D96A --out ~/edifact/packs/compiled

That writes the pack to ~/edifact/packs/compiled/untdid-d96a, and puts the four ISO 9735 syntax definitions in ~/edifact/packs/syntax beside it. Those four are the one input no ingestion can produce — the UNTDID omits the service definitions — so they reach a machine only because the tool ships them. Files already in that directory are left alone.

Use it

using Edifact.Core.Syntax;
using Edifact.Schema.Model;
using Edifact.Schema.Serialization;
using Edifact.Structure;

var syntax = new SyntaxPackSet("/home/me/edifact/packs/syntax");
var pack = PackReader.Read("/home/me/edifact/packs/compiled/untdid-d96a", syntax.For);

// Compiling a segment table is the expensive half — about 4 µs per segment to match afterwards —
// so a compiled message is worth keeping for as long as the pack is.
var spec = pack.TryGetMessage(new MessageKey("INVOIC", "D", "96A"))!;
var compiled = MessageCompiler.Compile(spec);

// One message: UNH through UNT, in interchange order. Edifact.Validation's EnvelopeReader is what
// splits a whole interchange into messages.
var segments = EdifactTokenizer.Tokenize(File.ReadAllText("message.edi")).Segments;

var match = StructureMatcher.Match(compiled, segments);

Console.WriteLine(match.Outcome);              // Complete, Repaired or Abandoned
Console.WriteLine(match.Tree.Describe());      // the tree, indented, as the CLI's --tree prints it

foreach (var finding in match.Findings) Console.WriteLine(finding);

Walk(match.Tree.Children);

static void Walk(IEnumerable<MessageNode> nodes, int depth = 0)
{
    foreach (var node in nodes)
    {
        Console.WriteLine($"{new string(' ', depth * 2)}{node.Label}  {node.Path}");

        switch (node)
        {
            case GroupNode group:
                Walk(group.Children, depth + 1);
                break;

            case SegmentNode segment:
                // segment.Item is the segment table entry it satisfies; segment.Segment is the
                // characters it was read from.
                break;

            case OrphanNode orphan:
                Console.WriteLine($"    nothing could place this: {orphan.Reason}");
                break;
        }
    }
}

Two contracts worth knowing

A tree always exists. Even for input that could not be matched at all, and even for a message type the directory does not define — MessageTree.OfOrphans covers that case. Every consumer downstream needs something to walk, and returning null on bad input would push the same conditional into all of them. What varies is ParseOutcome and how much of the tree is orphans.

Nothing is dropped. A segment nothing could account for stays in the tree as an OrphanNode, in the order it arrived, which is what lets the message be written back out character for character after a round trip through Edifact.Projection.

MessageCompiler.Compile takes an AmbiguityPolicy — which reading of an ambiguous segment table to prefer — and an optional StructureOverrides, three facts about a position (excluded, required, how often) as plain data. That last one is the seam Edifact.Overlays uses to apply a trading partner's guide without this package knowing what a guide is.

Where this sits

Edifact.Core       → nothing                the tokenizer, usable with no directory at all
Edifact.Schema     → Core                   what a release says
Edifact.Structure  → Core, Schema           matching a segment table       ← you are here
Edifact.Overlays   → Structure              what a guide says on top of a release
Edifact.Validation → Structure, Overlays    the usual entry point

Full documentation: https://github.com/WimSuenens/EDIFACT.

Licence

Apache-2.0. See the NOTICE in this package for what the wider project is derived from and under what terms.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Edifact.Structure:

Package Downloads
Edifact.Overlays

Trading partner and subset rules layered over a base directory — tightened cardinalities, restricted code values and conditional requirements — compiled into an effective message and evaluated with a ledger saying which overlay decided what.

Edifact.Validation

Validates an interchange against a directory and any overlays: envelope structure, segment and element cardinality, representation and code values, each finding carrying the rule that produced it and where in the source it applies.

Edifact.Projection

Projects a matched message into JSON or XML, either as the document it describes or as a linked form in which every value still points at the directory definition it was read against.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-preview.6 76 10/11/2026
1.0.0-preview.5 102 9/19/2026
1.0.0-preview.4 89 9/17/2026
1.0.0-preview.3 141 9/7/2026
1.0.0-preview.2 119 9/6/2026
1.0.0-preview.1 103 9/6/2026