Skip to content
Jake Aitchison edited this page Jan 20, 2023 · 3 revisions

Parser Options

As of nHapi version 3.1.0 we introduced ParserOptions which lets you configure the following things when parsing a message.

Option Since Version
AllowUnknownVersions 3.2.0
DefaultObx2Type 3.1.0
InvalidObx2Type 3.1.0
UnexpectedSegmentBehaviour 3.1.0
NonGreedyMode 3.1.0
IncludeLongNameInEncodedXml 3.2.0
DisableWhitespaceTrimmingOnAllXmlNodes 3.2.0
XmlNodeNamesToDisableWhitespaceTrimming 3.2.0
PrettyPrintEncodedXml 3.2.0

AllowUnknownVersions

Available Since 3.2.0, the default value is false.

If set to true, the parser will allow messages to parse, even if they contain a version which is not known to the parser.

When operating in this mode, if a message arrives which an unknown version string, the parser will attempt to parse it using a GenericMessage class instead of a specific nhapi structure class.

example usage:

var parser = new PipeParser();
var options = new ParserOptions { AllowUnknownVersions = true };

var parsed = parser.Parse(message, options);

DefaultObx2Type

Available Since 3.1.0, the default value is null, no fallback data type is used.

Default behaviour for OBX-2

In a normal OBX (Observation) segment, OBX-2 provides the datatype to be applied to OBX-5. So, for instance if an OBX repetition was conveying a timestamp (TS), it might look like this.

OBX||TS|||200901011259

If the OBX-2 value is missing (which sometimes happens because of a misbehaving sending system), you may see an error such as:

OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.

In this case, you may specify that nHapi should use a default type when none is found by specifying a default OBX-2 type using the ParserOptions.

example usage:

var parser = new PipeParser();
var options = new ParserOptions { DefaultObx2Type = "ST" };

var parsed = parser.Parse(message, options);

If this property is set, the value provides a default datatype (ST, NM, etc) for an OBX segment with a missing OBX-2 value. This is useful when parsing messages from systems which do not correctly populate OBX-2.

For example, if this property is set to ST, and the following OBX segment is encountered:

OBX|||||This is a value

It will be parsed as though it had read:

OBX||ST|||This is a value

If the OBX-2 value exists but is invalid, meaning that it has a value but that value is not a valid HL7 datatype (e.g. String instead of ST), you may specify a default type to assume if the OBX-2 value cannot be understood, see the option below.

InvalidObx2Type

Available Since 3.1.0, the default value is null, no fallback data type is used.

If this property is set, the value provides a default datatype (ST, NM, etc) for an OBX segment with an invalid OBX-2 value. This is useful when parsing messages from systems which do not correctly populate OBX-2.

For example, if this property is set to ST, and the following OBX segment is encountered:

OBX||INVALID|||This is a value

It will be parsed as though it had read:

OBX||ST|||This is a value

example usage:

var parser = new PipeParser();
var options = new ParserOptions { InvalidObx2Type = "ST" };

var parsed = parser.Parse(message, options);

UnexpectedSegmentBehaviour

Available Since 3.1.0, The default behaviour is AddInLine.

If you are processing messages with nonstandard segments (e.g. Z-segments) or segments which appear in a nonstandard location, the parser by default will use the AddInline option and add them where it finds them.

UnspectedSegmentBehaviour has 3 options.

Option Description
AddInline (Default) Add the segment as a nonstandard segment at the current location, even if the current location is in a child group within the message. You can read more about this here with examples.
DropToRoot Return the parser back to the root of the message (even if the last segment was in a group) and add the unexpected segment as a nonstandard segment.
ThrowHl7Exception Throw an HL7Exception

example usage:

var parser = new PipeParser();
var options = new ParserOptions
{
    UnexpectedSegmentBehaviour = UnexpectedSegmentBehaviour.DropToRoot
};

var msg = parser.Parse(message, options);

NonGreedyMode

Available Since 3.1.0, the default value is false.

Used to give the parser hints on how to proceed when the choice of where to put the next segment is ambiguous between moving to a child group later in the message structure or moving to a new repetition of a parent structure.

If set to true, pipe parser will be put in non-greedy mode. This setting applies only to the PipeParser and will have no effect on the XmlParser.

In non-greedy mode, if the message structure being parsed has an ambiguous choice of where to put a segment because there is a segment matching the current segment name in both a later position in the message, and in an earlier position as a part of a repeating group, the earlier position will be chosen.

This mode is useful for example when parsing OML^O21 messages containing multiple orders.

MSH
GROUP_1 (start)
{
   AAA
   BBB
   GROUP_2 (start)
   {
      AAA
   }
   GROUP_2 (end)
}
GROUP_1 (end)

For the above example, consider a message containing the following segments:

MSH
AAA
BBB
AAA

In this example, when the second AAA segment is encountered, there are two possible choices. It would be placed in GROUP_2, or it could be placed in a second repetition of GROUP_1. By default, it will be placed in GROUP_2, but in non-greedy mode it will be put in a new repetition of GROUP_1.

example usage:

var parser = new PipeParser();
var options = new ParserOptions { NonGreedyMode = true };

var parsed = parser.Parse(message, options);

IncludeLongNameInEncodedXml

Available Since 3.2.0, the default value is false.

Gets or Sets flag which allows the Description attribute LongName to be added in encoded xml with counter position.

<MSH.1 LongName="Field Separator">1</MSH.1>
<MSH.2 LongName="Encoding Characters">2</MSH.2>

example usage:

var xmlParser = new DefaultXMLParser();
var options = new ParserOptions { IncludeLongNameInEncodedXml = true };

var encoded = xmlParser.Encode(message, options);

DisableWhitespaceTrimmingOnAllXmlNodes

Available Since 3.2.0, the default value is false.

If set to true, the XMLParser is configured to treat all whitespace text nodes as literal, meaning that line breaks, tabs, multiple spaces, etc. will be preserved.

If set to false, any values passed to XmlNodeNamesToDisableWhitespaceTrimming will be superseded since all whitespace will treated as literal.

example usage:

var xmlParser = new DefaultXMLParser();
var options = new ParserOptions { DisableWhitespaceTrimmingOnAllXmlNodes = true };

var parsed = xmlParser.Parse(message, options);

XmlNodeNamesToDisableWhitespaceTrimming

Available Since 3.2.0, the default value is an Empty HashSet<string>.

Configures the XMLParser to treat all whitespace within the given HashSet<string> as literal, meaning that line breaks, tabs, multiple spaces, etc. will be preserved.

example usage:

var xmlParser = new DefaultXMLParser();
var options = new ParserOptions { XmlNodeNamesToDisableWhitespaceTrimming = true };

var parsed = xmlParser.Parse(message, options);

PrettyPrintEncodedXml

Available Since 3.2.0, the default value is true.

If set to true, the XMLParser will attempt to pretty-print the XML they generate.

This means the messages will look nicer to humans, but may take up slightly more space/bandwidth.

example usage:

var xmlParser = new DefaultXMLParser();
var options = new ParserOptions 
   {
      // only explicitly set here as an example
      PrettyPrintEncodedXml = true,
   };

var encoded = xmlParser.Encode(message, options);

example output:

<?xml version="1.0" encoding="utf-8"?>
<ADT_A01 xmlns="urn:hl7-org:v2xml">
    <MSH>
        <MSH.1>|</MSH.1>
        <MSH.2>^~\&amp;</MSH.2>
        <MSH.3>
            <HD.1>KISsystem</HD.1>
        </MSH.3>
        <MSH.4>
            <HD.1>ZTM</HD.1>
        </MSH.4>
        <MSH.5>
            <HD.1>NIDAklinikserver</HD.1>
        </MSH.5>
        <MSH.6>
            <HD.1>HL7Proxy</HD.1>
        </MSH.6>
        <MSH.7>
            <TS.1>201902271130</TS.1>
        </MSH.7>
        <MSH.9>
            <CM_MSG.1>ADT</CM_MSG.1>
            <CM_MSG.2>A01</CM_MSG.2>
        </MSH.9>
        <MSH.10>68371142</MSH.10>
        <MSH.11>
            <PT.1>P</PT.1>
        </MSH.11>
        <MSH.12>2.3</MSH.12>
    </MSH>
    <EVN>
        <EVN.1>A01</EVN.1>
        <EVN.2>
            <TS.1>201902271130</TS.1>
        </EVN.2>
        <EVN.3>
            <TS.1>201902271130</TS.1>
        </EVN.3>
    </EVN>
</ADT_A01>

if set to false you would get this:

<?xml version="1.0" encoding="utf-8"?><ADT_A01 xmlns="urn:hl7-org:v2xml"><MSH><MSH.1>|</MSH.1><MSH.2>^~\&amp;</MSH.2><MSH.3><HD.1>KISsystem</HD.1></MSH.3><MSH.4><HD.1>ZTM</HD.1></MSH.4><MSH.5><HD.1>NIDAklinikserver</HD.1></MSH.5><MSH.6><HD.1>HL7Proxy</HD.1></MSH.6><MSH.7><TS.1>201902271130</TS.1></MSH.7><MSH.9><CM_MSG.1>ADT</CM_MSG.1><CM_MSG.2>A01</CM_MSG.2></MSH.9><MSH.10>68371142</MSH.10><MSH.11><PT.1>P</PT.1></MSH.11><MSH.12>2.3</MSH.12></MSH><EVN><EVN.1>A01</EVN.1><EVN.2><TS.1>201902271130</TS.1></EVN.2><EVN.3><TS.1>201902271130</TS.1></EVN.3></EVN></ADT_A01>