Hello HAPI Team,
I am encountering an issue while parsing HL7 messages with a custom segment (ZRT) .I am using:
Java 21
Spring Boot 3.3.3
GenericParser from HAPI HL7 v2
Supporting HL7 versions v23 through v28
When I try to access the custom segment using Terser, I get the following exception:
```
ca.uhn.hl7v2.HL7Exception: Can't find ZRT as a direct child
at ca.uhn.hl7v2.util.SegmentFinder.getStructure(SegmentFinder.java:141)
at ca.uhn.hl7v2.util.SegmentFinder.getSegment(SegmentFinder.java:108)
at ca.uhn.hl7v2.util.Terser.getSegment(Terser.java:358)
at ca.uhn.hl7v2.util.Terser.get(Terser.java:324)
at org.techbd.ingest.service.ZrtSegmentParserTest.assertZrtFields(ZrtSegmentParserTest.java:63)
at org.techbd.ingest.service.ZrtSegmentParserTest.testCustomSegmentAfterPID(ZrtSegmentParserTest.java:49)
```
I am including the full JUnit test file for reference.
```
package org.service;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.parser.GenericParser;
import ca.uhn.hl7v2.util.Terser;
import ca.uhn.hl7v2.validation.impl.NoValidation;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ZrtSegmentParserTest {
private final GenericParser parser;
public ZrtSegmentParserTest() {
parser = new GenericParser();
parser.setValidationContext(new NoValidation()); // Disable HL7 validation
}
// ---------------------------
// Sample HL7 Messages
// ---------------------------
private static final String HL7_PUSH =
"MSH|^~\\&||DUMMYHOSP|||||ORU^R01|||2.5\r" +
"PID||123456^^^DUMMY:FACID^MRN|123456^^^DUMMY:FACID^MRN||Doe^John^A||19800101|M\r" +
"ZRT||ORU|R01|PUSH|||||123456^dummy:ABC~654321^dummy:XYZ|abcdef123456|userId^Test^User|add";
private static final String HL7_PBRD_ZRT_AFTER_MSH =
"MSH|^~\\&||DUMMYHOSP|||||ORU^R01|||2.5\r" +
"ZRT||ORU|R01|PBRD|||A1^DOE^JANE^ABC^ATT~B2^DOE^JANE^XYZ^CON|dummy:FAC|987654^dummy:ABC~456789^dummy:XYZ|abcdef987654||\r" +
"PID||123456^^^DUMMY:FACID^MRN|123456^^^DUMMY:FACID^MRN||Doe^John^A||19800101|M";
// ---------------------------
// Tests
// ---------------------------
@Test
@DisplayName("Test ZRT segment after MSH")
void testCustomSegmentAfterMSH() throws HL7Exception {
assertZrtFields(HL7_PBRD_ZRT_AFTER_MSH, "PBRD", "dummy:FAC", "ORU");
}
@Test
@DisplayName("Test ZRT segment after PID")
void testCustomSegmentAfterPID() throws HL7Exception {
assertZrtFields(HL7_PUSH, "PUSH", "dummy:ABC", "ORU");
}
// ---------------------------
// Helper Method
// ---------------------------
private void assertZrtFields(String hl7Message, String expectedDeliveryType,
String expectedFacility, String expectedMessageCode) throws HL7Exception {
Message message = parser.parse(hl7Message);
Terser terser = new Terser(message);
String messageCode = terser.get("/ZRT-2");
String triggerEvent = terser.get("/ZRT-3");
String deliveryType = terser.get("/ZRT-4");
String facility = terser.get("/ZRT-8");
assertThat(messageCode).isEqualTo(expectedMessageCode);
assertThat(triggerEvent).isNotEmpty();
assertThat(deliveryType).isEqualTo(expectedDeliveryType);
assertThat(facility).isEqualTo(expectedFacility);
System.out.printf("ZRT parsed: %s | %s | %s | %s%n",
messageCode, triggerEvent, deliveryType, facility);
}
}
```
Dependencies Used:
```
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-base</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v23</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v24</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v25</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v26</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v27</artifactId>
<version>${hapi.version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi</groupId>
<artifactId>hapi-structures-v28</artifactId>
<version>${hapi.version}</version>
</dependency>
```
Question:
How can I correctly parse a custom segment like ZRT using Terser when it may appear anywhere in the message (not necessarily after MSH)? Is there a recommended way to register custom segments so they can be reliably accessed, regardless of their position?
Thank you for your guidance!
Shreeja