HL7 Node Path Syntax (HPath)¶
HL7 is a messaging standard adopted by the healthcare industry for exchanging clinical and financial information between various healthcare IT systems. An HL7 node path (or HPath) is used to reference segments, fields, component and sub-components in an HL7 message. The HPath syntax conforms to the following pattern.
Node paths in this section can be used with getNode, getAllNodes, and other QIE functions that accept a nodePath parameter. See How Node Paths Resolve for behavior details and the Node Path Lookup Dialog to build and validate them interactively against a sample message.
| Segment ID [ Instance ] / Sub-Segment HPath – Field [ Field Instance ] . Component . Sub-Component | ||
|---|---|---|
| Element | Required | Description |
| Segment ID | Required * | The 3-character HL7 segment identifier (e.g. MSH or PID or EVN) |
| Instance | Optional |
|
| Sub-Segment HPath | Optional | A sub-segment HPath value can be appended to the Segment ID and Instance which identifies a sub-segment and field/component to select where the parent segment matches the Segment and Instance ID specified (TXA[@1=2]/OBX[@3=HPV]-5) |
| Field | Optional | The field index associated with the segment (1 or 2 or 3) |
| Field Instance | Optional | An HL7 field can contain multiple values or instances. To select a specific field instance, the Field Instance can be included in the HPath |
| Component | Optional | Some HL7 fields consist of multiple components. For example, name field in the Patient Identifier (PID) segment consists of Last Name^First Name^Middle Name. In these cases, a single component of a field can be selected by specifying the component instance as part of the HPath (5.1 or 5.2 or 5.3). You can also return all components in a field by using a wildcard HPath (5.*) with a getAllNodes(), it returns a String[] with the "Last Name" in the first element, "First Name" in the second element, and "Middle Name" in the third element. The wildcard cannot be used with a Sub-Component parameter (Example: 5.*.1 throws an exception). |
| Sub-Component | Optional | In the same way an HL7 field can consist of multiple components, a component can also consist of multiple sub-components. A sub-component can be selected by specifying the sub-component instance as part of the HPath (5.1.1 or 5.1.2 or 5.1.3). You can also return all sub-components in a field by using a wildcard HPath (5.1.*) with a getAllNodes(), it returns a String[] with all of the sub-components. |
* Segment ID is not required when specifying the root node identifier (/) as the node path
The HL7 message below is used with the HPath examples that follow:
MSH|^~\&|xyzEMR|xyzEMR|abcEMR|abcEMR|20120323220648||ADT^A08|20120323220648|P|2.3|EVN|A08|20100607113000||||PID|1|54664|125-54664||Mouse^Mickey^L||19410101||||||(615)123-4567^PRN^PH^^^615^1234567~(615)987-6543^ORN^CP^^^615^9876543|\
TXA|1|Summary|TX||hwinston&234||||||||||||AU|U||||hwinston^^^^^^^^^^^^^^20120301094500|\
OBX|1|ST|||Limb pain|||||||||20100607113000|\
OBX|2|ST|IMAGE||http://svr/docs/Enc/54664_Limb_Pain.html|||||||||20120301094500|\
TXA|2|Summary|TX||kstarr&378||||||||||||AU|U||||kstarr^^^^^^^^^^^^^^20120307113000|\
OBX|1|ST|||Chest pain|||||||||20100607113000|\
OBX|2|ST|IMAGE||http://svr/docs/Enc/54664_Chest_Pain.html|||||||||20120307113000|
| HL7 Node Path (HPath) | Description |
|---|---|
| / | Returns the entire HL7 message |
| EVN | Returns the EVN segment: EVN|A08|20100607113000|||| |
| EVN[1] | Returns the EVN segment: EVN|A08|20100607113000|||| |
| PID-5.2 | Returns the 2nd component of the 5th field of the first PID segment: Mickey |
| TXA-5.1 | Returns the 1st component of the 5th field of the first TXA segment: hwinston&234 |
| PID-5.* | Returns the 1st component of the 5th field of the first PID segment: Mouse When using getAllNodes() it returns a String[] with all three components |
| TXA-5.1.1 | Returns the 1st sub-component of the 1st component of the 5th field of the TXA segment: hwinston |
| TXA-5.1.2 | Returns the 2nd sub-component of the 1st component of the 5th field of the TXA segment: 234 |
| TXA-5.1.* | Returns the 1st sub-component of the 1st component of the 5th field of the TXA segment: hwinston When using getAllNodes() it returns a String[] with both sub-components. |
| TXA[2]-5.1.1 | Returns the 1st sub-component of the 1st component of the 5th field of the 2nd TXA segment: kstarr |
| TXA[@1=2]-5.1 | Returns the 1st component of the 5th field of the TXA segment with field 1 = '2': kstarr&378 |
| PID-13[@2=ORN] | Returns the 2nd phone number from PID-13 where the 2nd sub field is equal to ORN. (615)987-6543^ORN^CP^^^615^9876543 |
| TXA[2]/OBX[@3=IMAGE]-5 | Returns the 5th field of the OBX which is a child of the 2nd TXA segment and which has a value of `IMAGE` in field 3: http://svr/docs/Enc/54664_Chest_Pain.html |
| TXA[/OBX-5=Limb pain]-5 | Returns the 5th field of the TXA segment which has a child OBX segment with a value of 'Limb pain' in field 5: hwinston&234 |
| TXA[2;group=OBX] | Returns the last 3 segments (TXA, OBX, OBX) |
| TXA[group=!PID] | Returns the 4th, 5th, and 6th segments (TXA, OBX, OBX) |
| TXA[@4='']-5.1 | Returns the 1st component of the 5th field of the first TXA segment whose 4th field is empty: hwinston |
Wildcards can only appear at the innermost level
Wildcards must be at the deepest position in the node path: PID-3.* (all components) and PID-3.1.* (all subcomponents of component 1) are both valid, but PID-3.*.1 (a specific subcomponent across every component) is not. The HL7 model throws Component identifier cannot be a wild '*' when used with subComponent identifier: 'PID-3.*.1' on that combination. Iterate with getCount('PID-3.*') plus per-component getNode('PID-3.<i>.1') if you need that behavior.
Header Segments (FHS, BHS, MSH)¶
HL7 defines the field separator in the header segment itself. It is the 4th character of the segment, conventionally |. In the three header segments (FHS, BHS, and MSH) QIE returns that character as field 1, and the remaining fields keep their standard HL7 numbers.
| HL7 Node Path (HPath) | Description |
|---|---|
MSH-1 |
Returns the field separator defined by the message: \| |
MSH-2 |
Returns the encoding characters: ^~\& |
MSH-9 |
Returns the message type: ADT^A08 |
The field separator applies to every segment that follows the header in the message.
MSH-1 before QIE 26.2.1
In QIE 25.4.1 and earlier, getNode('MSH-1') returned the literal segment ID MSH instead of the field separator. Scripts written against those versions often extract the separator manually with StringUtils.substring(source.getNode('MSH'), 3, 4). That expression still works, but source.getNode('MSH-1') is preferred on 26.2.1 and later.
Filter Operators and Predicates¶
Segment filters of the form [@field=value] support several comparison operators and predicate functions for selecting a matching segment instance. The same operators and predicates are available for X12, JSON (predicate functions only), and DICOM node paths.
The examples below use the HL7 sample message shown above.
Comparison operators (used with @field or @field.component):
| Operator | Example | Returns |
|---|---|---|
= Equals |
OBX[@3=IMAGE]-5 |
The 5th field of the first OBX where field-3 equals IMAGE: http://svr/docs/Enc/54664_Limb_Pain.html |
!= Not equals |
OBX[@3!=IMAGE]-5 |
The 5th field of the first OBX where field-3 is not IMAGE: Limb pain |
> Greater than |
OBX[@1>1]-5 |
The 5th field of the first OBX where field-1 is greater than 1: http://svr/docs/Enc/54664_Limb_Pain.html |
< Less than |
OBX[@1<2]-5 |
The 5th field of the first OBX where field-1 is less than 2: Limb pain |
>= Greater than or equal |
OBX[@1>=2]-5 |
The 5th field of the first OBX where field-1 is 2 or greater: http://svr/docs/Enc/54664_Limb_Pain.html |
<= Less than or equal |
OBX[@1<=1]-5 |
The 5th field of the first OBX where field-1 is 1 or less: Limb pain |
The numeric operators require numeric values
>, >=, <, and <= parse both sides as numbers. If either the filter value or the field value in the message is not numeric, the node path throws Unable to compare values. Use =, !=, or a predicate function for non-numeric comparisons.
Matching empty fields
Use a single-quoted empty string as the value to match a segment where a field or component is blank, e.g. TXA[@4=''] selects TXA segments whose 4th field is empty. Single quotes are required; the value comparison is case-insensitive.
Predicate functions:
| Function | Signature | Example | Returns |
|---|---|---|---|
contains |
contains(node, value, caseSensitive) |
OBX[contains(@5, 'pain')]-5 |
Limb pain |
starts-with |
starts-with(node, value, caseSensitive) |
OBX[starts-with(@5, 'http')]-5 |
http://svr/docs/Enc/54664_Limb_Pain.html |
ends-with |
ends-with(node, value, caseSensitive) |
OBX[ends-with(@5, '.html')]-5 |
http://svr/docs/Enc/54664_Limb_Pain.html |
equals |
equals(node, value, caseSensitive) |
OBX[equals(@3, 'IMAGE')]-5 |
http://svr/docs/Enc/54664_Limb_Pain.html |
The caseSensitive argument is optional and defaults to false (case-insensitive matching). Pass true to force a case-sensitive comparison.
The equals function is equivalent to the = operator but adds explicit case-sensitivity control via caseSensitive.
Group filter:
| Form | Example | Returns |
|---|---|---|
group=X[,Y,...] |
TXA[1;group=OBX] |
The first TXA segment grouped with the OBX segments that follow it: TXA, OBX, OBX |
group=!X |
TXA[group=!TXA] |
The first TXA grouped with everything until the next TXA is encountered: TXA, OBX, OBX |
Compound filters: Two filters may be combined inside a single set of brackets using a semicolon (;). Only two filters are supported; a third or more does not parse.
TXA[2;group=OBX] combines an instance filter (2) with a group filter (group=OBX) to return the second TXA grouped with the OBX segments that follow it: TXA, OBX, OBX (the last three segments of the sample message).