-
-
Notifications
You must be signed in to change notification settings - Fork 36
Validation
Validation of EDI data is performed when reading or writing a stream of data using a schema object. All schemas are instantiated using a SchemaFactory
, by providing an InputStream
or URL
to a schema definition declared using EDI schema syntax. StAEDI supports two types of schemas - a control schema and a transaction schema.
Control schemas are used for handling the structural segments and elements of a message's envelop. That is, the interchange, group, and transaction header and trailer segments. Developers may provide their own control schemas or use those built in to StAEDI. When providing a custom control schema, it must be given to the EDIStreamReader
or EDIStreamWriter
prior to the start of an interchange.
Transaction schemas are used to validate the structure and content of a transaction/message. These are the segments and elements that occur within the transaction/message envelop (i.e. ST/SE or UNH/UNT). Developers must always provide a customer transaction schema if required. When reading EDI, the schema must be set on the EDIStreamReader
only at the point in the stream where the message header is being handled. In the case of X12, this would be any time between the start of the ST
segment and the end of the ST
segment. When writing EDI, the schema must be set on the EDIStreamWriter
at any time. Developers are responsible for managing whether the writer's transaction schema is set to null
or a non-null
value. The writer will always use the transaction schema if configured, unless the client application is writing control segment known to the currently-active control schema.
Validation errors are reported differently depending on whether an application is reading or writing data.
When reading, errors are signaled as stream events using one of the error values defined in EDIStreamEvent
. At the point in the stream where an error occurred, developers may call the getErrorType
method to obtain an EDIStreamValidationError
value that represents the current error.
When writing, errors will be thrown to the application using EDIValidationException
. Each instance of EDIValidationException
contains one or more errors that have occurred as a result of the most recent "write" method call. Additional errors may be retrieved using EDIValidationException's
getNextException` method.
Both the reader and the writer support the use of error reporters. Using the EDIInputFactory
or the EDIOutputFactory
, applications may register an EDIInputErrorReporter
or EDIOutputErrorReporter
instance. The reporters provide an interface for error notification that overrides the default behavior of having the error reported in-stream (during reading) or via an exception (during writing).
Often when handling EDI, programs need to make the distinction between the standard schema and an implementation of that schema. For example, the standard may declare that a particular segment may occur five times whereas an implementation agreed upon by trading partners may further define that the same segment may only occur twice, and may even define the allowable values or elements that may be used in each occurrence.
StAEDI supports implementation schemas as an extension to a standard and requires that both are defined in the schema XML file - see example in one of StAEDI's test cases. The information pertaining to the standard is defined by the <transaction>
element whereas the implementation is defined by the <implementation>
element that follows.
When defining an implementation of a segment or loop structure, the developer may either include or omit the structures components. If a component is omitted it is considered to be "not used" in that implementation.
Consider the following fictional segment definition and implementation.
<schema xmlns="http://xlate.io/EDISchema/v4">
<transaction>
<sequence>
<segment type="S13" maxOccurs="5" />
</sequence>
</transaction>
<implementation>
<sequence>
<!--
When element S13-01 contains "ONE", this occurrence
of S13 is used for validation.
Element S13-02 has a minimum occurs of "1", which means it is required for this occurrence.
Element S13-03 is not listed and would result in an error if found in the EDI data.
-->
<segment type="S13" discriminator="1">
<sequence>
<element position="1">
<enumeration>
<value>ONE</value>
</enumeration>
</element>
<element position="2" minOccurs="1" />
</sequence>
</segment>
<!--
When element S13-01 contains "TWO", this occurrence
of S13 is used for validation.
Element S13-02 is optional.
Element S13-03 is a required element in this occurrence.
-->
<segment type="S13" discriminator="1">
<sequence>
<element position="1">
<enumeration>
<value>TWO</value>
</enumeration>
</element>
<element position="2" />
<element position="3" minOccurs="1" />
</sequence>
</segment>
</sequence>
</implementation>
<elementType name="E001" base="string" maxLength="5" />
<elementType name="E002" base="string" maxLength="10" />
<segmentType name="S13">
<sequence>
<element type="E001" />
<element type="E002" />
<element type="E001" />
</sequence>
</segmentType>
</schema>
A simple transaction containing a single segment (S13) is defined along with an implementation that allows for two occurrences. The differences between the two occurrences are noted in the comments of the schema.
The occurrences are differentiated using an element referenced by the discriminator
attribute (the first position in the example). When using the discriminator
attribute, the corresponding element
must contain an enumeration of values that uniquely identifies the segment/loop occurrence from its peers (segments/loops of the same type in the standard).
If an implementation of a loop, segment, composite, or element does not declare minOccurs
or maxOccurs
, the value is inherited from the standard. If the standard does not declare the same attributes, the defaults are 0
for minOccurs
and 1
for maxOccurs
.
There may be times where you wish to relax validation for the content of some elements, but still ensure segments are received in the correct sequence. This is supported using the any
schema element as a child of compositeType
and segmentType
definitions. When any
is used in a segmentType
, validation will succeed for any simple or composite element encountered in the segment while parsing (except for binary data). Similarly, when any
is used in a compositeType
, validation will success for any component element in the composite.
<elementType name="E0143" number="143" base="string" minLength="3" maxLength="3"/>
<elementType name="E0329" number="329" base="string" minLength="4" maxLength="9" />
<compositeType name="C900">
<sequence>
<element type="E0143" minOccurs="1" />
<element type="E0329" />
<!--
Two (2) additional components MAY appear in C900 (maxOccurs = 2).
The first component is REQUIRED due to 'minOccurs'
-->
<any minOccurs="1" maxOccurs="2" />
</sequence>
<compositeType>
<segmentType name="FOO">
<sequence>
<element type="E0143" minOccurs="1" />
<composite type="C900" />
<!--
Five (5) additional elements and/or composites MAY appear in segment FOO (maxOccurs = 5).
None of the undefined elements are required (minOccurs = 0 by default)
-->
<any maxOccurs="5" />
</sequence>
<segmentType>
<segmentType name="BAR">
<sequence>
<!--
Twenty (20) elements and/or composites MAY appear in segment BAR (maxOccurs = 20).
None of the undefined elements are required (minOccurs = 0 by default)
-->
<any maxOccurs="20" />
</sequence>
<segmentType>