oais-structure-dfdl notes

This module bridges DFDL - the Open Grid Forum's Data Format Description Language (GFD.207) - onto the common StructureNode model, using Apache Daffodil 3.11.0 (daffodil-japi_2.13, Apache License 2.0, from Maven Central), the reference DFDL implementation.

How a format is described

A DFDL schema is an ordinary XML Schema whose elements carry dfdl: annotations saying how each one is laid out in the data: dfdl:length and dfdl:lengthKind, dfdl:byteOrder, dfdl:representation (binary/text), dfdl:encoding, dfdl:separator/dfdl:terminator for delimited text, dfdl:occursCount for repetition, and expressions such as dfdl:length="{ xs:int(../tns:labelLen) }" that take one field's length from another. Binary records, fixed-width text and delimited text (e.g. CSV) can all be described. See src/test/resources for a binary "point" record and a CSV example, and oais-structure-demo for more; archive-manager's RepInfo Tools also generates DFDL schemas from its engine-neutral description (counts as dfdl:occursCount, conditions and choices as dfdl:choiceDispatchKey/ dfdl:choiceBranchKey and occurrence expressions, CSV records with dfdl:separator/dfdl:terminator; and, when DFDL is among the chosen languages, bit fields with dfdl:lengthUnits="bits", explicit-length records, nil values with nillable/dfdl:nilValue, quoted CSV values with an escape-block dfdl:defineEscapeScheme, and dfdl:textNumberPattern number formats).

new DfdlFormatSpecification(schemaUri) points the adapter at a schema; the schema's default root element is parsed.

What DFDL is used for

This project's own examples are deliberately small (a binary "point" record and a CSV table, kept identical across the DFDL, Kaitai and DRB modules so their results can be compared). DFDL itself is used for much more. It was built for the text and binary record formats that predate XML and JSON, for example:

This list is a starting point, not exhaustive. The DFDL Schemas project on GitHub publishes open DFDL schemas for many of these formats (see below).

Galleries of examples

How the adapter works

Writing schemas Daffodil will accept

These all came up while getting this project's schemas to compile with real Daffodil:

Writing data back

DfdlStructureRepInfo is a WritableStructureRepInfo: write(dataObject, changes) parses into Daffodil's DOM infoset, sets each changed element's text (ElementPath -> value), and re-encodes the whole infoset with Daffodil's unparser; roundTrip(dataObject) writes it back unchanged and compares. Everything the schema describes is re-encoded from its value, so lengths and counts can change if the elements giving them are changed to match (or are computed with dfdl:outputValueCalc). What the infoset doesn't hold isn't written the way it was read: bytes after the described data, unused bytes inside an element of explicit length (written as the fill byte), and which of several delimiters or terminators the data used (the first is written - e.g. a newline after a last line that had none).

encode(infoset) writes a new file from values alone, with no original: the infoset is an XML document of the schema's elements, in its namespace and order, holding values as text. DfdlSchemaOutline.read(schemaText) gives the element tree such an infoset follows - names, namespaces, how often each occurs, value types, which are computed (dfdl:outputValueCalc) and which are alternatives of a choice - read from the schema as XML Schema, following named types and element references within the one document. archive-manager's Transformation builds infosets this way to rewrite a Data Object in another format.

Known limitations