A node defines a set of delimiters to be used in the external data representation for itself and its descendents in the hierarchical data structure. If a node defines a delimiter list, this negates any effect of any ancestor’s delimiter list on itself and its descendents. The delimiter list is typically specified on the Root node.
For example, if you want to parse the following data:
a^b|c^d|e |
you might define a Message Library as follows:
The delimiter list for this Message Library will be specified on the demo-otd element, so that it applies to the entire Message Library, and will have two levels:
Level 1
Delimiter |
Level 2
Delimiter ^
The Level 1 delimiter applies to the two elements and field 5, and the Level 2 delimiter applies to fields 1 through 4.
Delimiter lists can be much more complex than this very simple example. For instance, you can create multiple delimiters of different types at any given level, and you can specify a delimiter list on any node within the Message Library—not only the Root node as shown in the example. See Modifying a Message Library Using the Message Library Editor for a description of the procedure for creating a Delimiter List.
Delimiter Properties
Delimiters are defined using the Delimiter List Editor. The Delimiter properties and values are displayed in the following.
Table 1 Delimiter Properties
Delimiter Properties and Value Options |
||
---|---|---|
Property |
Option |
Description |
Level |
Child level beneath defining node. |
|
Type |
escape |
Escape sequence. |
repeat |
Array delimiter/separator. |
|
normal |
Terminator. |
|
Delimiter Bytes |
Delimiter (single or multiple characters). |
|
Precedence |
See Precedence. |
|
Optional Mode |
never |
Do not allow on input, do not emit on output (empty field between delimiters implies zero length data field). |
allow |
Skip empty field if present; if absent, do not delimit on output. |
|
cheer |
Skip empty field if present; if absent, do delimit on output. |
|
force |
Require empty, delimited field on input; always delimit on output. |
|
Terminator Mode |
never |
Do not allow on input, do not emit on output (pure separator). |
allow |
Allow on input, do not emit on output. |
|
cheer |
Allow on input, always emit on output. |
|
force |
Require on input, always emit on output (pure terminator). |
Type Property - Escape Option
An escape delimiter is simply a sequence that will be recognized and ignored during parsing. Its purpose is to allow the use of escape sequences to embed byte sequences in data that would otherwise be seen as delimiter occurrences.
For example, if there is a normal delimiter “+” at a given level, and we define an escape delimiter “\+”, then aaa+b\+c+ddd will parse as three fields: aaa, b\+c, and ddd. If the escape delimiter were not defined, the sequence would then parse as four fields: aaa, b\, c, and ddd.
If there is only an escape delimiter on a given level, however, it presents a no delimiter defined situation for delim and array nodes.
Delimiter Bytes
There is essentially no limitation on what characters you can use as delimiters; however, you obviously want to avoid characters that can be confused with data or interfere with escape sequences. The backslash (\) is normally used as an escape character. The HL7 protocol uses a double backslash as part of an escape sequence that provides special text formatting instructions.
You should avoid using a colon (:) as a delimiter character, since it is used as a literal in system-generated time strings. This can interfere with recovery procedures, for example following a Domain shutdown.
Terminator Mode Property
Consider the tree structure shown in the previous example, where the node a has a pipe (|) as its delimiter, the sub-node b has a tilde (~) as its delimiter, and sub-node c has an asterisk (*) as its delimiter.
Option |
Input |
Output |
---|---|---|
never |
c| |
c| |
allow |
c| or c*| |
c| |
cheer |
c| or c*| |
c*| |
force |
c*| |
c*| |
Optional Mode Property
Consider the tree structures shown in the figures, where the node a has a pipe (|) as its delimiter, and the sub-nodes b, c, and d all have asterisks (*) as their delimiters.
Example 1: Sub-node c is optional. Sub-node c and sub-node d must have different values for the match parameter.
Option |
Input |
Output |
---|---|---|
never |
b*d| |
b*d| |
allow |
b**d| |
b*d| |
cheer |
b**d| |
b**d| |
force |
b**d| |
b**d| |
Example 2: Both sub-node c and sub-node d are optional.
Option |
Input |
Output |
---|---|---|
never |
b| |
b| |
allow |
b|, b*|, or b**| |
b| |
cheer |
b|, b*|, or b**| |
b**| |
force |
b**| |
b**| |
Precedence
Precedence indicates the priority of a certain delimiter, relative to the other delimiters. By default, all delimiters are at precedence 10, which means they are all considered the same; fixed fields are hard-coded at precedence 10. Delimiters on parent nodes are not considered when parsing the child fields; only the child’s delimiter (or if it is a fixed field, its length).
Changing the precedence of a delimiter will cause them to be applied to the input data-stream in different ways. For example:
Root node
element (type delim, delimiter = “^”, repeat)
field1 (type fixed, length = 5)
field2 (type fixed, length = 8, optional)
Although this will parse ”abcde12345678^zyxvuABCDEFGH’, it will not parse the text ”abcde^zyxvuABCDEFGH’ even though the second fixed field is optional. The reason is that the element’s delimiter is ignored within the fixed field because they have the same precedence. If you want the element’s delimiter to be examined within the fixed field data, you must change its precedence, for example: