hl7 java 解析
原文链接 http://blog.csdn.net/ycyangcai/article/details/6643784
Hl7引擎的目标主要是解决将数据按HL7协议的要求标准化,和标准业务的集成和不同系统间标准业务数据的同步。在多年的医院信息化过程中,HL7标准组织和解析最复杂了,下面是我用了多年HL7引擎解析,主要有两个版本1.C#,2.JAVA版的。
本次公开JAVA的
1 //引擎类: 2 3 package com.xxxx.hl7; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.OutputStreamWriter; 7 import java.io.Writer; 8 import java.util.List; 9 import org.dom4j.Document; 10 import org.dom4j.DocumentHelper; 11 import org.dom4j.Element; 12 import org.dom4j.Node; 13 import org.dom4j.io.OutputFormat; 14 import org.dom4j.io.XMLWriter; 15 //HL7 转换为XML 16 public class HL7ToXmlConverter { 17 // 18 public static String ConvertToXml(String sHL7){ 19 Document document = ConvertToXmlObject(sHL7); 20 String hl7str = document.asXML(); 21 return hl7str; 22 } 23 // 24 public static String ConvertToXml(Document document){ 25 String hl7str = document.asXML(); 26 return hl7str; 27 } 28 29 public static Document ConvertToXmlObject(String sHL7){ 30 Document document = CreateXmlDoc(); 31 //把HL7分成段 32 String[] sHL7Lines = sHL7.split("\n"); 33 //去掉XML的关键字 34 for (int i = 0; i < sHL7Lines.length; i++){ 35 sHL7Lines[i] = sHL7Lines[i].replace("^~\\&", "").replace("MSH", "MSH|"); 36 } 37 for (int i = 0; i < sHL7Lines.length; i++){ 38 // 判断是否空行 39 if (sHL7Lines[i] != null){ 40 String sHL7Line = sHL7Lines[i]; 41 //通过/r 或/n 回车符分隔 42 String[] sFields = GetMessgeFields(sHL7Line); 43 // 为段(一行)创建第一级节点 44 Element el = document.getRootElement().addElement(sFields[0]); 45 // 循环每一行 46 Boolean isMsh=true; 47 for (int a = 1; a < sFields.length; a++){ 48 //是否包括HL7的连接符^~\\& 49 if (sFields[a].indexOf('^')>0 || sFields[a].indexOf('~')>0 || sFields[a].indexOf('\\')>0 || sFields[a].indexOf('&')>0 ){ 50 //0:如果这一行有任一分隔符 51 //开始操作~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 //通过~分隔 53 String[] sComponents = GetRepetitions(sFields[a]); 54 if (sComponents.length > 1){ 55 //1:如果可以分隔 0001^郭靖^体检号^EQ^AND~0002^东一区^病区号^EQ^AND 56 for (int b = 0; b < sComponents.length; b++){ 57 // Element fieldEl1 = el.addElement(sFields[0] + "." + a); 58 CreateComponents(el,sComponents[b],sFields[0],a,b); 59 } 60 } 61 else{ 62 //1:如果真的只有一个值的 0001^郭靖^体检号^EQ^AND 63 // 为字段创建第二级节点 64 // Element fieldEl = el.addElement(sFields[0] + "." + a); 65 CreateComponents(el,sFields[a],sFields[0],a,0); 66 //fieldEl.setText(sFields[a]+"11111111111111"); 67 } 68 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 } 70 else{ 71 //0:如果这一行没有任何分隔符 72 // 为字段创建第二级节点 73 Element fieldEl = el.addElement(sFields[0] + "." + a); 74 fieldEl.setText(sFields[a]); 75 } 76 } 77 }//end if 78 }//end for 79 //修改MSH.1 和 MSH.2的值 80 document.selectSingleNode("HL7Message/MSH/MSH.1").setText("|"); 81 document.selectSingleNode("HL7Message/MSH/MSH.2").setText("~^\\&"); 82 // document.selectNodes("MSH/MSH.1"); 83 return document; 84 } 85 @SuppressWarnings("unused") 86 private static Element CreateComponents(final Element el,final String hl7Components,String sField,int a,int b){ 87 Element componentEl = el.addElement(sField + "." + a); 88 // Element componentEl =el;//.addElement(sField + "." + a + "." + b); 89 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 90 //通过&分隔 91 String[] subComponents = GetSubComponents(hl7Components); 92 if (subComponents.length > 1){ 93 //2.如果有字组,一般是没有的。。。 子分组 用&很少用 94 } 95 else{ 96 //2.如果没有了,就用^分组 97 String[] sRepetitions = GetComponents(hl7Components); 98 if (sRepetitions.length > 1){ 99 Element repetitionEl = null; 100 for (int c = 0; c < sRepetitions.length; c++){ 101 repetitionEl = componentEl.addElement(sField + "." + a + "." + (c+1)); 102 repetitionEl.setText(sRepetitions[c]); 103 } 104 } 105 else{ 106 componentEl.setText(hl7Components); 107 } 108 } 109 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 110 return el; 111 } 112 113 /// <summary> 114 /// 通过|分隔 字段 115 /// </summary> 116 /// <param name="s"></param> 117 /// <returns></returns> 118 119 private static String[] GetMessgeFields(String s){ 120 return s.split("\\|"); 121 } 122 /// <summary> 123 /// 通过^分隔 组字段 124 /// </summary> 125 /// <param name="s"></param> 126 /// <returns></returns> 127 128 private static String[] GetComponents(String s){ 129 return s.split("\\^"); 130 } 131 /// <summary> 132 /// 通过&分隔 子分组组字段 133 /// </summary> 134 /// <param name="s"></param> 135 /// <returns></returns> 136 137 private static String[] GetSubComponents(String s){ 138 return s.split("&"); 139 } 140 /// <summary> 141 /// 通过~分隔 重复 142 /// </summary> 143 /// <param name="s"></param> 144 /// <returns></returns> 145 private static String[] GetRepetitions(String s){ 146 return s.split("~"); 147 } 148 /// <summary> 149 /// 创建XML对象 150 /// </summary> 151 /// <returns></returns> 152 private static Document CreateXmlDoc(){ 153 Document output = DocumentHelper.createDocument(); 154 //生成一个接点 155 Element rootNode = output.addElement("HL7Message"); 156 return output; 157 } 158 public static String GetText(Document document, String path){ 159 Node node = document.selectSingleNode("HL7Message/"+path); 160 if (node != null){ 161 return node.getText(); 162 } 163 else{ 164 return null; 165 } 166 } 167 public static String GetText(Document document, String path,int index){ 168 List nodes = document.selectNodes("HL7Message/"+path); 169 if(nodes!=null){ 170 return ((Node)nodes.get(index)).getText(); 171 } 172 else{ 173 return null; 174 } 175 } 176 177 // 178 public static List GetTexts(Document document, String path){ 179 List nodes = document.selectNodes("HL7Message/"+path); 180 return nodes; 181 } 182 183 // 184 public static void writeDocument(Document document, String filepath){ 185 try{ 186 //读取文件 187 // FileWriter fileWriter = new FileWriter(filepath); 188 Writer writer = new OutputStreamWriter(new FileOutputStream(filepath),"utf-8"); 189 //设置文件编码 190 OutputFormat xmlFormat = new OutputFormat(); 191 xmlFormat.setEncoding("utf-8"); 192 //创建写文件方法 193 XMLWriter xmlWriter = new XMLWriter(writer,xmlFormat); 194 //写入文件 195 xmlWriter.write(document); 196 //关闭 197 xmlWriter.close(); 198 }catch(IOException e){ 199 System.out.println("文件没有找到"); 200 e.printStackTrace(); 201 } 202 } 203 }
单元测试调用类:
1 String myHL7string="MSH|^~\\&|455755610_0100||0200||20110624160404|000|QRY^A19^QRY_A19|0123456001|P|2.6\nQRD|||||||||0001^郭靖^体检号^EQ^AND~0002^东一区^病区号^EQ^AND\nQRF||20110627|20110803"; 2 Document document = HL7ToXmlConverter.ConvertToXmlObject(myHL7string); 3 //获取事件 4 String eventName = HL7ToXmlConverter.GetText(document, "MSH/MSH.9/MSH.9.3"); 5 System.out.println("eventName:"+eventName); 6 // List nodeValue = document.selectNodes("MSH.1"); 7 String nodeValue = document.selectSingleNode("HL7Message/MSH/MSH.1").getText(); 8 String nodeValue2 = document.selectSingleNode("HL7Message/MSH/MSH.3").getText(); 9 // DocumentElement.SelectNodes(path); 10 System.out.println(nodeValue+":"+nodeValue2); 11 String value = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1",0); 12 String value1 = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1",1); 13 String value2 = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1"); 14 System.out.println(value+":"+value1+":"+value2); 15 List<Node> list = HL7ToXmlConverter.GetTexts(document, "QRD/QRD.9/QRD.9.1"); 16 for(Node node : list) 17 { 18 System.out.println(":"+node.getText()); 19 } 20 System.out.println(HL7ToXmlConverter.ConvertToXml(myHL7string));