java解析HL7协议报文工具(v24版)

java解析HL7协议报文工具

因为项目需要解析HL7协议报文,网上找到的工具都是解析成带位置信息的xml格式或者json格式,然后需要自己根据需要获取的位置来获取信息。而在生成的HL7协议报文的时候也是需要先生成xml或json格式再进行转换。想着希望找到一个直接解析生成类然后直接用的工具。
后来我找到了这个ca.uhn.hapi,能将HL7报文直接解析成相应的类,通过调用:PipeParser.parse(message, hl7str)来解析报文,将数据填充到message类里面,其中message是工具里面的继承Message类的子类,例如:QBP_Q11、RSP_K23等。而生成HL7报文的时候又可以调用message.encode()来生成,不过需要先设置MSH头,调用:

message.getMSH().getFieldSeparator().setValue("|");
message.getMSH().getEncodingCharacters().setValue("^~\\&");

设置完可以调用msh里面的get方法来设置值,例如:

message.getMSH().getMsh11_ProcessingID().getProcessingID().setValue("P");
message.getMSH().getMsh17_CountryCode().setValue("CHN");

maven导入工具包:

<dependency>
    <groupId>ca.uhn.hapi</groupId>
    <artifactId>hapi-base</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>ca.uhn.hapi</groupId>
    <artifactId>hapi-structures-v24</artifactId>
    <version>2.3</version>
</dependency>

后来因为接入的项目用到的协议和ca.uhn.hapi工具里面已经定义好的类所解析的报文结构不一致,所以需要自己去编写工具来自定义解析和生成相应的HL7报文,比如以下报文的RSP_ZP7在工具包里面没有相应的类结构对应(\r为回车):

MSH|^~\\&|PMI||01||20170719143120||RSP^ZP7|YY00000001|P|2.4|\rMSA|AA|YY00000001|[MsgInfo] Method Type: ZP7 -Success Flag: AA -MSG: success QueryPerson return message success.\rQAK||||0|0|0\rQPD|\rIN1|6|0|8\rQRI|15.014454851245674|3|

下面我写了几个工具类来实现方便调用,HL7Helper类主要是设置数据和获取数据,UserDefineComposite类用于自定义数据类型,UserDefineMessage类用于自定义message类型:

HL7Helper类:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.AbstractComposite;
import ca.uhn.hl7v2.model.AbstractPrimitive;
import ca.uhn.hl7v2.model.AbstractSegment;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.Type;
import ca.uhn.hl7v2.model.Varies;
import ca.uhn.hl7v2.parser.PipeParser;

/**
 * @author SamJoke
 */
public class HL7Helper {
   

    private static Method method = null;

    static {
        try {
            method = AbstractSegment.class.getDeclaredMethod("add", Class.class, boolean.class, int.class, int.class,
                    Object[].class, String.class);
            method.setAccessible(true);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    /**
     * 自定义添加AbstractSegment类的字段类型,然后可以用getFeild方法进行赋值,例子参考:
     * testSegmentAddFeildRequest()
     * 
     * @param obj
     *            AbstractSegment对象
     * @param c
     *            数据类型
     * @param required
     *            是否必填
     * @param maxReps
     *            数组长度
     * @param length
     *            字节长度
     * @param constructorArgs
     *            构造器
     * @param name
     *            字段名
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public static void segmentAddFeild(AbstractSegment obj, Class<? extends Type> c, boolean required, int maxReps,
            int length, Object[] constructorArgs, String name)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        method.invoke(obj, c, required, maxReps, length, constructorArgs, name);
    }

    public static void segmentAddFeild(AbstractSegment obj, Class<? extends Type> c, int maxReps, int length,
            Message msg) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        segmentAddFeild(obj, c, false, maxReps, length, new Object[] { msg }, "user define");
    }

    public static void segmentAddFeild(AbstractSegment obj, Class<? extends Type> c, int length, Message msg)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        segmentAddFeild(obj, c, false, 1, length, new Object[] { msg }, "user define");
    }

//    public static void segmentAddFeild(AbstractSegment obj, HL7DataType hl7DateType, Message msg)
//            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
   
//        segmentAddFeild(obj, hl7DateType.getCls(), false, hl7DateType.getMaxReps(), hl7DateType.getLength(),
//                new Object[] { msg }, "user define");
//    }

    @SuppressWarnings("unchecked")
    public static <T> T getField(AbstractSegment obj, int pos, int index, Class<T> cls) throws HL7Exception {
        return (T) obj.getField(pos, index);
    }

    /**
     * 将hl7str协议报文转换为指定的Message类(可自定义),例子参考:testSegmentAddFeildResponse()
     * 
     * @param msg
     *            Message类型,如ADT_A01
     *
  • 11
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
首先,需要了解 HL7 格式的基本结构和各个字段的含义。然后,可以使用 Delphi 中的字符串处理函数和正则表达式等工具解析。 以下是一个简单的示例代码: ```delphi unit HL7Parser; interface uses SysUtils, RegularExpressions; type TField = record Value: string; Repetitions: array of string; end; TSegment = record Name: string; Fields: array of TField; end; THL7Message = class private FSegments: array of TSegment; function GetSegment(Index: Integer): TSegment; function GetSegmentCount: Integer; public constructor Create(const MessageText: string); property SegmentCount: Integer read GetSegmentCount; property Segments[Index: Integer]: TSegment read GetSegment; end; implementation constructor THL7Message.Create(const MessageText: string); var SegmentsText: TArray<string>; FieldsText: TArray<string>; RepetitionsText: TArray<string>; i, j, k: Integer; Segment: TSegment; Field: TField; Match: TMatch; begin SegmentsText := MessageText.Split([#13#10], TStringSplitOptions.ExcludeEmpty); SetLength(FSegments, Length(SegmentsText)); for i := 0 to High(SegmentsText) do begin Segment.Name := SegmentsText[i].Substring(0, 3); FieldsText := SegmentsText[i].Substring(4).Split(['|']); SetLength(Segment.Fields, Length(FieldsText)); for j := 0 to High(FieldsText) do begin RepetitionsText := FieldsText[j].Split(['^']); Field.Value := RepetitionsText[0]; SetLength(Field.Repetitions, Length(RepetitionsText) - 1); for k := 1 to High(RepetitionsText) do begin Field.Repetitions[k - 1] := RepetitionsText[k]; end; Segment.Fields[j] := Field; end; FSegments[i] := Segment; end; end; function THL7Message.GetSegment(Index: Integer): TSegment; begin Result := FSegments[Index]; end; function THL7Message.GetSegmentCount: Integer; begin Result := Length(FSegments); end; end. ``` 使用示例: ```delphi var HL7Message: THL7Message; i, j: Integer; begin HL7Message := THL7Message.Create('MSH|^~\&|SENDINGAPP|SENDINGFAC|RECEIVINGAPP|RECEIVINGFAC|20200828090109||ADT^A01|MSG00001|P|2.3|||'); for i := 0 to HL7Message.SegmentCount - 1 do begin WriteLn(HL7Message.Segments[i].Name); for j := 0 to High(HL7Message.Segments[i].Fields) do begin WriteLn(' Field ' + IntToStr(j + 1) + ': ' + HL7Message.Segments[i].Fields[j].Value); if Length(HL7Message.Segments[i].Fields[j].Repetitions) > 0 then begin for k := 0 to High(HL7Message.Segments[i].Fields[j].Repetitions) do begin WriteLn(' Repetition ' + IntToStr(k + 1) + ': ' + HL7Message.Segments[i].Fields[j].Repetitions[k]); end; end; end; end; end; ``` 这个示例代码只是一个简单的实现,实际使用中可能需要更复杂的逻辑来处理各种情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值