Hl7引擎 2.X

来源:互联网 发布:老k平面户型优化设计 编辑:程序博客网 时间:2024/05/16 15:02

Hl7引擎的目标主要是解决将数据按HL7协议的要求标准化,和标准业务的集成和不同系统间标准业务数据的同步。在多年的医院集成平台信息化过程中,HL7标准组织和解析最复杂了,下面是我用了多年HL7引擎解析,因公司升级使用了HL73.0版本,决定把HL72.X引擎放到博客上保存。

 

(引擎解析类)Decode.cs

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


测试方法:

[csharp] view plain copy
 print?
  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. string sHL7asXml = HL7ToXmlConverter.ConvertToXml(myHL7string);  
  3. XmlDocument xmlObject = HL7ToXmlConverter.ConvertToXmlObject(myHL7string);  
  4. String value = HL7ToXmlConverter.GetText(xmlObject, "QRD/QRD.9/QRD.9.0",0);  
  5. String value2 = HL7ToXmlConverter.GetText(xmlObject, "QRD/QRD.9/QRD.9.0");  
  6. String nodeValue = xmlObject.DocumentElement.SelectSingleNode("MSH/MSH.1").InnerText;  
  7. String nodeValue2 = xmlObject.DocumentElement.SelectSingleNode("QRD/QRD.9/QRD.9.0").InnerText;     
0 0