HL7 卫生信息交换标准(Health Level 7)

标准化的卫生信息传输协议,是医疗领域不同应用之间电子传输的协议。HL7汇集了不同厂商用来设计应用软件之间接口的标准格式,它将允许各个医疗机构在异构系统之间,进行数据交互。

HL7的主要应用领域是HIS/RIS,主要是规范HIS/RIS系统及其设备之间的通信,它涉及到病房和病人信息管理、化验系统、药房系统、放射系统、收费系统等各个方面。HL7的宗旨是开发和研制医院数据信息传输协议和标准,规范临床医学和管理信息格式,降低医院信息系统互连的成本,提高医院信息系统之间数据信息共享的程度。

Health Level 7中的“Level 7”是指OSI的七层模型中的最高一层,第七层。但这并不是说它遵循OSI第七层的定义数据元素,它只是用来构成它自己的抽象数据类型和编码规则。它也没有规定规范说明如何支持OSI第一到第六层的数据。

HL7 基本语法 每一个 HL7 消息由一些段组成,段由<CR> (即<0x0D>)结尾。消息以 utf-8 格式传输 
每个段由三个字符的段名和固定数目的域组成,域由组件和子组件构成,在每个消息的 MSH 段定义各 个组成单元的分隔符。 
例如: 
MSH|^~&|Z3|Zybio|||20180514144801||ORU^R01|2018481414050147670|P|2.3.1||||||UNICODE 
其中: 
在 MSH 之后的五个字符定义用来区分各域、组件和子组件的分隔符。迈瑞 HL7 标准使用下表的字符: 
| 域分隔符 
^ 组件分隔符 
& 子组件分隔符 
~ 重复分隔符 
\ 转义字符 
 
MSH 的第一个域包括各个分隔符。后面的有些域都是空的,因为他们是可选的并且迈瑞 HL7 接口没有 使用它,详细的域的定义和选取在后面说明。 
域 9: 包含消息类型和事件(ORU、R01) 
域 10: 包含一个唯一标识该消息的消息 ID 
域 11: 包含处理 ID(P 表示产品) 
域 12: 定义消息使用的 HL7 版本(2.3.1)

服务端代码

using hepu.BloodModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;namespace hepu
{public partial class Blood5_TCP : Form{public Blood5_TCP(){InitializeComponent();}public delegate void showData(string msg);//委托,防止跨线程的访问控件,引起的安全异常private const int bufferSize = 8000;//缓存空间private TcpClient client;private TcpListener server;/// <summary>/// 结构体:Ip、端口/// </summary>struct IpAndPort{public string Ip;public string Port;}private void Blood5_TCP_Load(object sender, EventArgs e){}private void button1_Click(object sender, EventArgs e){if (txtIP.Text.Trim() == string.Empty){return;}if (txtPort.Text.Trim() == string.Empty){return;}Thread thread = new Thread(reciveAndListener);//如果线程绑定的方法带有参数的话,那么这个参数的类型必须是object类型,所以讲ip,和端口号 写成一个结构体进行传递IpAndPort ipHePort = new IpAndPort();ipHePort.Ip = txtIP.Text;//服务器IPipHePort.Port = txtPort.Text;//为程序设置端口thread.Start((object)ipHePort);}/// <summary>/// 侦听客户端的连接并接收客户端发送的信息/// </summary>/// <param name="ipAndPort">服务端Ip、侦听端口</param>private void reciveAndListener(object ipAndPort){IpAndPort ipHePort = (IpAndPort)ipAndPort;IPAddress ip = IPAddress.Parse(ipHePort.Ip);server = new TcpListener(ip, int.Parse(ipHePort.Port));server.Start();//启动监听rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "服务端开启侦听....\n");//  btnStart.IsEnabled = false;//获取连接的客户端对象client = server.AcceptTcpClient();rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "有客户端请求连接,连接已建立!");//AcceptTcpClient 是同步方法,会阻塞进程,得到连接对象后才会执行这一步  //获得流NetworkStream reciveStream = client.GetStream();#region 循环监听客户端发来的信息do{byte[] buffer = new byte[bufferSize];int msgSize;try{lock (reciveStream){msgSize = reciveStream.Read(buffer, 0, bufferSize);}if (msgSize == 0)return;string msg = Encoding.Default.GetString(buffer, 0, bufferSize);//将hl7数据包转换成xml  方便提取数据NewBlood5 blood5= FormatXml(Encoding.Default.GetString(buffer, 0, msgSize));//这里只做单条数据传输  工作站没有批量发送    如果有批量的话可以判断数据包开头<SB>MSH|^~\&|公司名称(发送端公司名称)|XXX型号(发送端设备名称)||//出现了几次,如果出现多次.    New一个list集合   将实体类添加到集合里YLB_OneSynchronous(blood5);//rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "\n客户端曰:" + result + "\r\n");}catch (Exception ex){server.Stop();string aa = ex.Message;MessageBox.Show(aa);rtbtxtShowData.Invoke(new showData(rtbtxtShowData.AppendText), "\n 出现异常:连接被迫关闭");break;}} while (true);#endregion}/// <summary>/// 将数据包转换成xml格式   提取有效参数/// </summary>/// <param name="hl7data"></param>/// <returns></returns>public NewBlood5  FormatXml(string hl7data){ XmlDocument xmlObject = HL7ToXmlConverter.ConvertToXmlObject(hl7data);var xns = xmlObject.SelectSingleNode("HL7Message");XmlNodeList xnl = xns.ChildNodes;NewBlood5 blood5 = new NewBlood5();blood5.Barcode = HL7ToXmlConverter.GetText(xmlObject, "PID/PID.2", 0);//样本编号   没有重复的节点blood5.WBC = GetValue(xnl, "WBC");//白细胞数目   //重复的节点根据名字取值blood5.Neu = GetValue(xnl, "NeuCount");//中性粒细胞数目    Neu# return blood5;}public string GetValue(XmlNodeList xnl,string 项目名) {string Value = string.Empty;if (!string.IsNullOrEmpty(项目名)){foreach (XmlNode xn in xnl){XmlElement xe = (XmlElement)xn;XmlNodeList xnl2 = xe.ChildNodes;foreach (XmlNode xn2 in xnl2){XmlElement xe2 = (XmlElement)xn2;if (xe2.InnerText.Equals(项目名)){var objs = new{Name = xe.GetElementsByTagName("OBX.5")};Value = objs.Name[0].InnerText;return Value;}}}} return Value;}}
}

解析hl7数据为xml

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;namespace hepu.BloodModel
{/// <summary>/// HL7解析器/// </summary>public class HL7ToXmlConverter{private static XmlDocument _xmlDoc;/// <summary>/// 把HL7信息转成XML形式/// 分隔顺序 \n,|,~,^,&/// </summary>/// <param name="sHL7">HL7字符串</param>/// <returns></returns>public  string ConvertToXml(string sHL7){_xmlDoc = ConvertToXmlObject(sHL7);return _xmlDoc.OuterXml;}public static XmlDocument ConvertToXmlObject(string sHL7){_xmlDoc = CreateXmlDoc();//把HL7分成段string[] sHL7Lines = sHL7.Split('\r');//这里一定注意   经过测试,TCP方式接收的用\r分隔,webService方式接收的用\n分隔//去掉XML的关键字for (int i = 0; i < sHL7Lines.Length; i++){sHL7Lines[i] = Regex.Replace(sHL7Lines[i], @"[^ -~]", "");}for (int i = 0; i < sHL7Lines.Length; i++){// 判断是否空行if (sHL7Lines[i] != string.Empty){string sHL7Line = sHL7Lines[i];//通过/r 或/n 回车符分隔string[] sFields = HL7ToXmlConverter.GetMessgeFields(sHL7Line);// 为段(一行)创建第一级节点XmlElement el = _xmlDoc.CreateElement(sFields[0]);_xmlDoc.DocumentElement.AppendChild(el);// 循环每一行for (int a = 0; a < sFields.Length; a++){// 为字段创建第二级节点XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString());//是否包括HL7的连接符if (sFields[a] != @"^~\&"){//0:如果这一行有任何分隔符//通过~分隔string[] sComponents = HL7ToXmlConverter.GetRepetitions(sFields[a]);if (sComponents.Length > 1){//1:如果可以分隔for (int b = 0; b < sComponents.Length; b++){XmlElement componentEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString());//通过&分隔 string[] subComponents = GetSubComponents(sComponents[b]);if (subComponents.Length > 1){//2.如果有字组,一般是没有的。。。for (int c = 0; c < subComponents.Length; c++){//修改了一个错误string[] subComponentRepetitions = GetComponents(subComponents[c]);if (subComponentRepetitions.Length > 1){for (int d = 0; d < subComponentRepetitions.Length; d++){XmlElement subComponentRepEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString() + "." + d.ToString());subComponentRepEl.InnerText = subComponentRepetitions[d];componentEl.AppendChild(subComponentRepEl);}}else{XmlElement subComponentEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString());subComponentEl.InnerText = subComponents[c];componentEl.AppendChild(subComponentEl);}}fieldEl.AppendChild(componentEl);}else{//2.如果没有字组了,一般是没有的。。。string[] sRepetitions = HL7ToXmlConverter.GetComponents(sComponents[b]);if (sRepetitions.Length > 1){XmlElement repetitionEl = null;for (int c = 0; c < sRepetitions.Length; c++){repetitionEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString() + "." + c.ToString());repetitionEl.InnerText = sRepetitions[c];componentEl.AppendChild(repetitionEl);}fieldEl.AppendChild(componentEl);el.AppendChild(fieldEl);}else{componentEl.InnerText = sComponents[b];fieldEl.AppendChild(componentEl);el.AppendChild(fieldEl);}}}el.AppendChild(fieldEl);}else{//1:如果不可以分隔,可以直接写节点值了。fieldEl.InnerText = sFields[a];el.AppendChild(fieldEl);}}else{//0:如果不可以分隔,可以直接写节点值了。fieldEl.InnerText = sFields[a];el.AppendChild(fieldEl);}}}}return _xmlDoc;}/// <summary>/// 通过|分隔 字段/// </summary>/// <param name="s"></param>/// <returns></returns>private static string[] GetMessgeFields(string s){return s.Split('|');}/// <summary>/// 通过^分隔 组字段/// </summary>/// <param name="s"></param>/// <returns></returns>private static string[] GetComponents(string s){return s.Split('^');}/// <summary>/// 通过&分隔 子分组组字段/// </summary>/// <param name="s"></param>/// <returns></returns>private static string[] GetSubComponents(string s){return s.Split('&');}/// <summary>/// 通过~分隔 重复/// </summary>/// <param name="s"></param>/// <returns></returns>private static string[] GetRepetitions(string s){return s.Split('~');}/// <summary>/// 创建XML对象/// </summary>/// <returns></returns>private  static XmlDocument CreateXmlDoc(){XmlDocument output = new XmlDocument();XmlElement rootNode = output.CreateElement("HL7Message");output.AppendChild(rootNode);return output;}public  string GetText(XmlDocument xmlObject, string path){XmlNode node = xmlObject.DocumentElement.SelectSingleNode(path);if (node != null){return node.InnerText;}else{return null;}}public string GetValue(XmlNodeList xnl,string 项目名) {string Value = string.Empty;foreach (XmlNode xn in xnl){XmlElement xe = (XmlElement)xn;XmlNodeList xnl2 = xe.ChildNodes;foreach (XmlNode xn2 in xnl2){XmlElement xe2 = (XmlElement)xn2;if (xe2.InnerText.Equals(项目名)){var objs = new{Name = xe.GetElementsByTagName("OBX.5") };Value = objs.Name[0].InnerText;return Value;}}}return Value;}public static string GetText(XmlDocument xmlObject, string path, int index){XmlNodeList nodes = xmlObject.DocumentElement.SelectNodes(path);if (index <= nodes.Count){return nodes[index].InnerText;}else{return null;}}public  String[] GetTexts(XmlDocument xmlObject, string path){XmlNodeList nodes = xmlObject.DocumentElement.SelectNodes(path);String[] arr = new String[nodes.Count];int index = 0;foreach (XmlNode node in nodes){arr[index++] = node.InnerText;}return arr;}}}

测试:

使用tcp调试工具作为客户端发送hl7数据(工具可在我的资源中下载)https://download.csdn.net/download/qq_39569480/15703156

以接受病历号和HCT为例

病历号是唯一的节点

HCT的父节点名称有重复

重复时遍历所有节点   根据hct查找

public string GetValue(XmlNodeList xnl,string 项目名) {string Value = string.Empty;if (!string.IsNullOrEmpty(项目名)){foreach (XmlNode xn in xnl){XmlElement xe = (XmlElement)xn;XmlNodeList xnl2 = xe.ChildNodes;foreach (XmlNode xn2 in xnl2){XmlElement xe2 = (XmlElement)xn2;if (xe2.InnerText.Equals(项目名)){var objs = new{Name = xe.GetElementsByTagName("OBX.5")};Value = objs.Name[0].InnerText;return Value;}}}} return Value;}

C#解析HL7协议数据2.X相关推荐

  1. 「智慧医疗」1分钟学会解析HL7协议数据

    一.什么是HL7? 标准化的卫生信息传输协议,是医疗领域不同应用之间电子传输的协议.HL7汇集了不同厂商用来设计应用软件之间接口的标准格式,它将允许各个医疗机构在异构系统之间,进行数据交互.HL7 建 ...

  2. 用C语言解析通讯协议数据,C/C++知识点之服务端使用c++实现websocket协议解析及通信...

    C/C++知识点之服务端使用c++实现websocket协议解析及通信 小标 2018-12-03 来源 : 阅读 2289 评论 0 摘要:本文主要向大家介绍了 C/C++知识点之服务端使用c++实 ...

  3. C#解析ASTM1394-97协议数据

    ASTM协议为标准组织美国材料实验室协会(ASTM)制定的在医疗临床实验室仪器和计算机系统间传输信息的一个标准,此标准有多个版本,本文中提到的版本为E1394-97(下文中提到的ASTM均为ASTM的 ...

  4. springboot接收HL7协议报文 HAPI(SpringBoot版本)

    1.maven依赖 <dependency><groupId>ca.uhn.hapi</groupId><artifactId>hapi-base< ...

  5. JAVA实现报文解析:协议的数据类型和完整的报文结构解析

    **JAVA实现GBT32960报文解析系列文章链接:** JAVA实现GBT32960报文解析(一):协议的数据类型和完整的报文结构解析 JAVA实现GBT32960报文解析(二):数据包结构解析源 ...

  6. pelco-d协议数据解析示例

    pelco-d协议数据解析示例 2014-08-14 21:57 286人阅读 评论(0) 收藏 举报 本文章已收录于: 分类: 程序编程(12) 作者同类文章X 代码工人的仓库(36) 作者同类文章 ...

  7. MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

    文章目录 一.MQTT协议 二.协议详解 2.1 协议结构 2.1.1 固定报头 2.1.2 可变报头 2.1.3 有效载荷 三.具体协议报文详解 3.1 连接服务器报文详解 3.2 发布消息报文详解 ...

  8. 协议数据的发送与解析

    协议数据的发送与解析 对于C,C++等语言而言,我们常见各种各样的基本数据类型,比如char,int,float,double等等.为了回顾一一下具体的数据类型,下面我们看下面的一张表来回顾一下. 类 ...

  9. python解析flv协议(AMF数据)

    学习python也有1周了,因为之前学习了golang,所以觉得python和golang有很多类似的地方,比如切片和语法,python的确是一门很好的语言,至少你了解了之后才会发现其实它很强大,编写 ...

  10. 基于`IRIS`,动态解析`HL7`消息

    文章目录 基于`IRIS`,动态解析`HL7`消息 什么是`HL7` `HL7` 版本 `HL7` 消息结构 段(`Segment`) 字段(`Field`) `HL7` 数据类型 在`IRIS`中查 ...

最新文章

  1. AI一分钟 | 小米MIX 2S将于3月27号发布,搭载骁龙845;张朝阳:在研究区块链 但相信AI的力量
  2. 豪斯荷尔德变换及变形QR算法对矩阵进行奇异值分解VB算法
  3. 如何有效完成医学科研课题设计?
  4. 搜索引擎的选择—百度还是谷歌?
  5. MySQL_自定义函数
  6. pika集群水平扩展——让性能容量不再受限
  7. 斯坦福 AIMI 打造世界更大的开源医学数据集
  8. KITTI数据集评估方法小结
  9. 毕业设计 stm32单片机智能药箱设计与实现 - 物联网
  10. 微信扫一扫地标识别技术揭秘
  11. deep_sort文章阅读(一)yolo的训练:PART1: 安装opencv(为了make时opencv=1)
  12. Git:rebase 是什么
  13. 手写Google第一代分布式计算框架 MapReduce
  14. java实现sug,Java SuggestionResult類代碼示例
  15. 海蜘蛛软路由linux安装教程,软路由安装设置教程【详细步骤】-太平洋IT百科
  16. 重装 Macos sierra系统 U盘
  17. uni-app学习路线 - 计划
  18. 又老了一岁,祝自己生日快乐。。。
  19. 【案例】云卷云舒,ArcGIS成就时空交错的新闻播报
  20. 算法的浪漫 - 相交链表

热门文章

  1. mybatis mysql xml配置_Mybatis-Spring连接mysql 8.0配置步骤出错的解决方法
  2. 4204. 构造矩阵
  3. spark java.lang.StackOverflowError
  4. hive collect_set mysql group_concat
  5. 有史以来最容易理解的控制反转(IoC)与注入依赖(DI)
  6. SLAM学习笔记-------------(10)后端2
  7. 华为ospf配置命令_教你使用华为Ensp模拟器配置OSPF路由协议(一)
  8. 算法的优缺点_逻辑回归算法的优缺点
  9. Oracle在线撤销表空间,Oracle创建、管理撤销表空间
  10. this关键字在构建错误实例时使用说明