HL7解析器

关于医疗的项目,用了HL7协议,以下是解析的代码:

HL7解析器:

using System;
using System.Text;
using System.Xml;
using System.IO;

namespace CA2
{
    /// <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();
            sHL7 = sHL7.Replace("\\v","").Replace("\\u001c","");
            sHL7 = sHL7.Replace("\\r","\n");
            //把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);
                    if (string.IsNullOrWhiteSpace(sFields[0]) == false)
                    {
                        // 为段(一行)创建第一级节点
                        if (string.IsNullOrWhiteSpace(sFields[0]) == false)
                        {
                            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;

        }

        public static string FormatXml(string sUnformattedXml)
        {

            XmlDocument xd = new XmlDocument();
            xd.LoadXml(sUnformattedXml);
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            XmlTextWriter xtw = null;
            try
            {
                xtw = new XmlTextWriter(sw);
                xtw.Formatting = Formatting.Indented;
                xtw.Indentation = 1;
                xtw.IndentChar = '\t';
                xd.WriteTo(xtw);
            }
            finally
            {
                if (xtw != null)
                    xtw.Close();
            }
            return sb.ToString();
        }
    }
}

程序入口:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值