HL7 2.X解析 for C#版

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

(引擎解析类)Decode.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;

namespace com.china.hl7 {
    /// <summary>
    /// HL7解析器
    /// </summary>
    public static class HL7ToXmlConverter {
        private static XmlDocument _xmlDoc;

        /// <summary>
        /// 把HL7信息转成XML形式
        /// 分隔顺序 \n,|,~,^,&
        /// </summary>
        /// <param name="sHL7">HL7字符串</param>
        /// <returns></returns>
        public static string ConvertToXml(string sHL7) {
            _xmlDoc = ConvertToXmlObject(sHL7);
            return _xmlDoc.OuterXml;
        }

        public static XmlDocument ConvertToXmlObject(string sHL7) {
            _xmlDoc = CreateXmlDoc();

            //把HL7分成段
            string[] sHL7Lines = sHL7.Split('\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 static string GetText(XmlDocument xmlObject, string path) {
            XmlNode node = xmlObject.DocumentElement.SelectSingleNode(path);
            if (node != null) {
                return node.InnerText;
            } else {
                return null;
            }
        }

        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 static 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;
        }
    }
}

测试方法:

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";
Document document = HL7ToXmlConverter.ConvertToXmlObject(myHL7string);

//获取事件
String eventName = HL7ToXmlConverter.GetText(document, "MSH/MSH.9/MSH.9.3");
System.out.println("eventName:" + eventName);

//  List nodeValue = document.selectNodes("MSH.1");
String nodeValue = document.selectSingleNode("HL7Message/MSH/MSH.1").getText();
String nodeValue2 = document.selectSingleNode("HL7Message/MSH/MSH.3").getText();
// DocumentElement.SelectNodes(path);
System.out.println(nodeValue + ":" + nodeValue2);

String value = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1", 0);
String value1 = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1", 1);
String value2 = HL7ToXmlConverter.GetText(document, "QRD/QRD.9/QRD.9.1");
System.out.println(value + ":" + value1 + ":" + value2);

List < Node > list = HL7ToXmlConverter.GetTexts(document, "QRD/QRD.9/QRD.9.1");
for (Node node: list) {
    System.out.println(":" + node.getText());
}

System.out.println(HL7ToXmlConverter.ConvertToXml(myHL7string));
声明:本文采用 BY-NC-SA 协议进行授权,本文链接:HL7 2.X解析 for C#版

发表评论