HL7解析器

最近作了關於醫療的項目,用了HL7協議,如下是解析的代碼:node

HL7解析器:c++

 1 using System;  2 using System.Text;  3 using System.Xml;  4 using System.IO;  5 
 6 namespace CA2  7 {  8     /// <summary>
 9     /// HL7解析器  10     /// </summary>
 11     public static class HL7ToXmlConverter  12  {  13         private static XmlDocument _xmlDoc;  14 
 15         /// <summary>
 16         /// 把HL7信息轉成XML形式  17         /// 分隔順序 \n,|,~,^,&  18         /// </summary>
 19         /// <param name="sHL7">HL7字符串</param>
 20         /// <returns></returns>
 21         public static string ConvertToXml(string sHL7)  22  {  23             _xmlDoc = ConvertToXmlObject(sHL7);  24             return _xmlDoc.OuterXml;  25  }  26 
 27         public static XmlDocument ConvertToXmlObject(string sHL7)  28  {  29             _xmlDoc = CreateXmlDoc();  30             sHL7 = sHL7.Replace("\\v","").Replace("\\u001c","");  31             sHL7 = sHL7.Replace("\\r","\n");  32             //把HL7分紅段
 33             string[] sHL7Lines = sHL7.Split('\n');  34 
 35             ////去掉XML的關鍵字
 36             //for (int i = 0; i < sHL7Lines.Length; i++)  37             //{  38             // sHL7Lines[i] = Regex.Replace(sHL7Lines[i], @"[^ -~]", "");  39             //}
 40 
 41             for (int i = 0; i < sHL7Lines.Length; i++)  42  {  43                 // 判斷是否空行
 44                 if (sHL7Lines[i] != string.Empty)  45  {  46                     string sHL7Line = sHL7Lines[i];  47                     //經過/r 或/n 回車符分隔
 48                     string[] sFields = HL7ToXmlConverter.GetMessgeFields(sHL7Line);  49                     if (string.IsNullOrWhiteSpace(sFields[0]) == false)  50  {  51                         // 爲段(一行)建立第一級節點
 52                         if (string.IsNullOrWhiteSpace(sFields[0]) == false)  53  {  54                             XmlElement el = _xmlDoc.CreateElement(sFields[0]);  55  _xmlDoc.DocumentElement.AppendChild(el);  56                             // 循環每一行
 57                             for (int a = 0; a < sFields.Length; a++)  58  {  59                                 // 爲字段建立第二級節點
 60                                 XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString());  61                                 //是否包括HL7的鏈接符
 62                                 if (sFields[a] != @"^~\&")  63                                 {//0:若是這一行有任何分隔符  64                                     //經過~分隔
 65                                     string[] sComponents = HL7ToXmlConverter.GetRepetitions(sFields[a]);  66                                     if (sComponents.Length > 1)  67                                     {//1:若是能夠分隔
 68                                         for (int b = 0; b < sComponents.Length; b++)  69  {  70                                             XmlElement componentEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString());  71                                             //經過&分隔 
 72                                             string[] subComponents = GetSubComponents(sComponents[b]);  73                                             if (subComponents.Length > 1)  74                                             {//2.若是有字組,通常是沒有的。。。
 75                                                 for (int c = 0; c < subComponents.Length; c++)  76  {  77                                                     //修改了一個錯誤
 78                                                     string[] subComponentRepetitions = GetComponents(subComponents[c]);  79                                                     if (subComponentRepetitions.Length > 1)  80  {  81                                                         for (int d = 0; d < subComponentRepetitions.Length; d++)  82  {  83                                                             XmlElement subComponentRepEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString() + "." + d.ToString());  84                                                             subComponentRepEl.InnerText = subComponentRepetitions[d];  85  componentEl.AppendChild(subComponentRepEl);  86  }  87  }  88                                                     else
 89  {  90                                                         XmlElement subComponentEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString());  91                                                         subComponentEl.InnerText = subComponents[c];  92  componentEl.AppendChild(subComponentEl);  93 
 94  }  95  }  96  fieldEl.AppendChild(componentEl);  97  }  98                                             else
 99                                             {//2.若是沒有字組了,通常是沒有的。。。
100                                                 string[] sRepetitions = HL7ToXmlConverter.GetComponents(sComponents[b]); 101                                                 if (sRepetitions.Length > 1) 102  { 103                                                     XmlElement repetitionEl = null; 104                                                     for (int c = 0; c < sRepetitions.Length; c++) 105  { 106                                                         repetitionEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString()); 107                                                         repetitionEl.InnerText = sRepetitions[c]; 108  componentEl.AppendChild(repetitionEl); 109  } 110  fieldEl.AppendChild(componentEl); 111  el.AppendChild(fieldEl); 112  } 113                                                 else
114  { 115                                                     componentEl.InnerText = sComponents[b]; 116  fieldEl.AppendChild(componentEl); 117  el.AppendChild(fieldEl); 118  } 119  } 120  } 121  el.AppendChild(fieldEl); 122  } 123                                     else
124                                     {//1:若是不能夠分隔,能夠直接寫節點值了。
125                                         fieldEl.InnerText = sFields[a]; 126  el.AppendChild(fieldEl); 127  } 128  } 129                                 else
130                                 {//0:若是不能夠分隔,能夠直接寫節點值了。
131                                     fieldEl.InnerText = sFields[a]; 132  el.AppendChild(fieldEl); 133  } 134  } 135  } 136  } 137  } 138  } 139             return _xmlDoc; 140  } 141 
142         /// <summary>
143         /// 經過|分隔 字段 144         /// </summary>
145         /// <param name="s"></param>
146         /// <returns></returns>
147         private static string[] GetMessgeFields(string s) 148  { 149             return s.Split('|'); 150  } 151 
152         /// <summary>
153         /// 經過^分隔 組字段 154         /// </summary>
155         /// <param name="s"></param>
156         /// <returns></returns>
157         private static string[] GetComponents(string s) 158  { 159             return s.Split('^'); 160  } 161 
162         /// <summary>
163         /// 經過&分隔 子分組組字段 164         /// </summary>
165         /// <param name="s"></param>
166         /// <returns></returns>
167         private static string[] GetSubComponents(string s) 168  { 169             return s.Split('&'); 170  } 171 
172         /// <summary>
173         /// 經過~分隔 重複 174         /// </summary>
175         /// <param name="s"></param>
176         /// <returns></returns>
177         private static string[] GetRepetitions(string s) 178  { 179             return s.Split('~'); 180  } 181 
182         /// <summary>
183         /// 建立XML對象 184         /// </summary>
185         /// <returns></returns>
186         private static XmlDocument CreateXmlDoc() 187  { 188             XmlDocument output = new XmlDocument(); 189             XmlElement rootNode = output.CreateElement("HL7Message"); 190  output.AppendChild(rootNode); 191             return output; 192  } 193 
194         public static string GetText(XmlDocument xmlObject, string path) 195  { 196             XmlNode node = xmlObject.DocumentElement.SelectSingleNode(path); 197             if (node != null) 198  { 199                 return node.InnerText; 200  } 201             else
202  { 203                 return null; 204  } 205  } 206 
207         public static string GetText(XmlDocument xmlObject, string path, int index) 208  { 209             XmlNodeList nodes = xmlObject.DocumentElement.SelectNodes(path); 210             if (index <= nodes.Count) 211  { 212                 return nodes[index].InnerText; 213  } 214             else
215  { 216                 return null; 217  } 218  } 219 
220         public static String[] GetTexts(XmlDocument xmlObject, string path) 221  { 222             XmlNodeList nodes = xmlObject.DocumentElement.SelectNodes(path); 223             String[] arr = new String[nodes.Count]; 224             int index = 0; 225             foreach (XmlNode node in nodes) 226  { 227                 arr[index++] = node.InnerText; 228  } 229             return arr; 230 
231  } 232 
233         public static string FormatXml(string sUnformattedXml) 234  { 235 
236             XmlDocument xd = new XmlDocument(); 237  xd.LoadXml(sUnformattedXml); 238             StringBuilder sb = new StringBuilder(); 239             StringWriter sw = new StringWriter(sb); 240             XmlTextWriter xtw = null; 241             try
242  { 243                 xtw = new XmlTextWriter(sw); 244                 xtw.Formatting = Formatting.Indented; 245                 xtw.Indentation = 1; 246                 xtw.IndentChar = '\t'; 247  xd.WriteTo(xtw); 248  } 249             finally
250  { 251                 if (xtw != null) 252  xtw.Close(); 253  } 254             return sb.ToString(); 255  } 256  } 257 }

程序入口:ui

using System; using System.Collections.Generic; using System.Xml; namespace CA2 { class Program { static void Main(string[] args) { String myHL7string = @"\vMSH|^~\\&||Mindray|||20191113163421||ORU^R01|2|P|2.3.1||||||UNICODE\rPID|1||^^^^MR||^患者名稱|||男\rPV1|1||兒科\rOBR|1||7|00001^Automated Count^99MRC|||20191113102722|||單位||||||||||||||HM||||||||人員\rOBX|1|IS|08001^Take Mode^99MRC||C||||||F\rOBX|2|IS|08002^Blood Mode^99MRC||P||||||F\rOBX|3|IS|08003^Test Mode^99MRC||CBC+DIFF+CRP||||||F\rOBX|4|IS|01002^Ref Group^99MRC||兒童||||||F\rOBX|5|NM|30525-0^Age^LN||3|yr|||||F\rOBX|6|NM|6690-2^WBC^LN||10.62|10*9/L|4.00-12.00|N|||F\rOBX|7|NM|704-7^BAS#^LN||0.01|10*9/L|0.00-0.10|N|||F\rOBX|8|NM|706-2^BAS%^LN||0.1|%|0.0-1.0|N|||F\rOBX|9|NM|751-8^NEU#^LN||8.06|10*9/L|2.00-8.00|H~N|||F\rOBX|10|NM|770-8^NEU%^LN||75.8|%|50.0-70.0|H~N|||F\rOBX|11|NM|711-2^EOS#^LN||0.02|10*9/L|0.02-0.80|N|||F\rOBX|12|NM|713-8^EOS%^LN||0.2|%|0.5-5.0|L~N|||F\rOBX|13|NM|731-0^LYM#^LN||2.11|10*9/L|0.80-7.00|N|||F\rOBX|14|NM|736-9^LYM%^LN||19.9|%|20.0-60.0|L~N|||F\rOBX|15|NM|742-7^MON#^LN||0.42|10*9/L|0.12-1.20|N|||F\rOBX|16|NM|5905-5^MON%^LN||4.0|%|3.0-12.0|N|||F\rOBX|17|NM|789-8^RBC^LN||4.29|10*12/L|3.50-5.20|N|||F\rOBX|18|NM|718-7^HGB^LN||117|g/L|120-160|L~N|||F\rOBX|19|NM|787-2^MCV^LN||80.1|fL|80.0-100.0|N|||F\rOBX|20|NM|785-6^MCH^LN||27.2|pg|27.0-34.0|N|||F\rOBX|21|NM|786-4^MCHC^LN||339|g/L|310-370|N|||F\rOBX|22|NM|788-0^RDW-CV^LN||12.7|%|11.0-16.0|N|||F\rOBX|23|NM|21000-5^RDW-SD^LN||37.1|fL|35.0-56.0|N|||F\rOBX|24|NM|4544-3^HCT^LN||34.4|%|35.0-49.0|L~N|||F\rOBX|25|NM|777-3^PLT^LN||224|10*9/L|100-300|N|||F\rOBX|26|NM|32623-1^MPV^LN||8.7|fL|6.5-12.0|N|||F\rOBX|27|NM|32207-3^PDW^LN||16.3||15.0-17.0|N|||F\rOBX|28|NM|10002^PCT^99MRC||0.194|%|0.108-0.282|N|||F\rOBX|29|NM|30392-5^NRBC#^LN||0.002|10*9/L|0.000-9999.999|N|||F\rOBX|30|NM|26461-4^NRBC%^LN||0.02|%|0.00-9999.99|N|||F\rOBX|31|NM|10014^PLCR^99MRC||19.6|%|11.0-45.0|N|||F\rOBX|32|NM|10013^PLCC^99MRC||44|10*9/L|30-90|N|||F\rOBX|33|NM|26477-0^*ALY#^LN||0.00|10*9/L|0.00-0.20|N|||F\rOBX|34|NM|13046-8^*ALY%^LN||0.0|%|0.0-2.0|N|||F\rOBX|35|NM|10000^*LIC#^99MRC||0.00|10*9/L|0.00-0.20|N|||F\rOBX|36|NM|10001^*LIC%^99MRC||0.0|%|0.0-2.5|N|||F\rOBX|37|NM|71426-1^FR-CRP^LN||12.56|mg/L|0.00-4.00|H~N|||F\rOBX|38|NM|15001^WBC Histogram. Left Line^99MRC||13||||||F\rOBX|39|NM|15003^WBC Histogram. Middle Line^99MRC||36||||||F\rOBX|40|NM|15002^WBC Histogram. Right Line^99MRC||71||||||F\rOBX|41|NM|15004^WBC Histogram. Meta Length^99MRC||1||||||F\rOBX|42|NM|15009^WBC Histogram. Total^99MRC||7675||||||F\rOBX|43|ED|15008^WBC Histogram. BMP^99MRC|||F|\rOBX|59|NM|15208^WBC DIFF Scattergram. FSC-LOG dimension^99MRC||0||||||F\r\u001c\r"; Test(myHL7string); Console.ReadLine(); } static void Test(string myHL7string) { string sHL7asXml = HL7ToXmlConverter.ConvertToXml(myHL7string); XmlDocument xmlObject = HL7ToXmlConverter.ConvertToXmlObject(myHL7string); XmlNodeList allOBX = xmlObject.SelectNodes("//OBX"); int i = 1; List<OutAnalyzerResultItemDTO> listOutAnalyzerResultItemDTO = new List<OutAnalyzerResultItemDTO>(); var strSpecimenTime = HL7ToXmlConverter.GetText(xmlObject, "OBR/OBR.7"); OutAnalyzerResultDTO outAnalyzerResultDTO = new OutAnalyzerResultDTO() { FlowNum = int.Parse(HL7ToXmlConverter.GetText(xmlObject, "OBR/OBR.3")), SpecimenTime = DateTime.Parse(string.Format("{0}-{1}-{2} {3}:{4}:{5}", strSpecimenTime.Substring(0, 4), strSpecimenTime.Substring(4, 2), strSpecimenTime.Substring(6, 2), strSpecimenTime.Substring(8, 2), strSpecimenTime.Substring(10, 2), strSpecimenTime.Substring(12, 2))), }; foreach (XmlElement element in allOBX) { if (i >= 6 && i <= 37) { listOutAnalyzerResultItemDTO.Add(new OutAnalyzerResultItemDTO() { ItemCode = FormatItemCode(element.GetElementsByTagName("OBX.3")[0].InnerText),//項目對照編碼
                        HLFlag = FormatFlag(element.SelectSingleNode("OBX.8/OBX.8.0"), element.SelectSingleNode("OBX.8")),//高低標記
                        ReferenceRange = element.GetElementsByTagName("OBX.7")[0].InnerText,//參考值
                        Result = element.GetElementsByTagName("OBX.5")[0].InnerText,//檢測結果
                        Uint = element.GetElementsByTagName("OBX.6")[0].InnerText,//檢測單位
 }); } i += 1; } outAnalyzerResultDTO.resultItemDTOs = listOutAnalyzerResultItemDTO; listOutAnalyzerResultItemDTO.ForEach(x => { Console.Write("代碼:" + x.ItemCode); Console.Write(" 結果:" + x.Result); Console.Write(" 參考值:" + x.ReferenceRange); Console.Write(" 單位:" + x.Uint); Console.WriteLine(" 高低值:" + x.HLFlag); }); } static string FormatItemCode(string allStr) { var a1 = allStr.IndexOf("^"); var a2 = allStr.LastIndexOf("^"); var aa = allStr.Substring(a1 + 1, a2 - a1 - 1); return aa; } static string FormatFlag(XmlNode str1, XmlNode str2) { return str1 == null ? str2.InnerText : str1.InnerText; } } }
相關文章
相關標籤/搜索