HL7 2.6解析转XML(C#版)

Posted yisheng163

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HL7 2.6解析转XML(C#版)相关的知识,希望对你有一定的参考价值。

HL7 2.6解析转XML(C#版)

项目中需要解析HL7,所以在网上找到解析代码,但错误很多,所以我修改了一下,测试好用。

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

namespace PT.Common
{
    /// <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;
        }

        /// <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;
        }
        
        /// <summary>
        /// 读取XML某节点值
        /// </summary>
        /// <param name="xmlObject"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetText(XmlDocument xmlObject, string path)
        {
            XmlNode node = xmlObject.DocumentElement.SelectSingleNode(path);
            if (node != null)
            {
                return node.InnerText;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 读取XML某节点组的第index项
        /// </summary>
        /// <param name="xmlObject"></param>
        /// <param name="path"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        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;
            }
        }

        /// <summary>
        /// 读取XML某节点组
        /// </summary>
        /// <param name="xmlObject"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// HL7字符串转XML
        /// </summary>
        /// <param name="sHL7"></param>
        /// <returns></returns>
        public static XmlDocument ConvertToXmlObject(string sHL7)
        {
            _xmlDoc = CreateXmlDoc();

            //把HL7分成段
            string[] sHL7Lines = sHL7.Split(‘\r‘);//经过测试,TCP方式接收的用\r分隔,webService方式接收的用\n分隔
            
            //过滤一些字符
            //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];//某一段

                    //通过“|”分隔
                    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 (1==1)//1:如果可以用“~”分隔,继续分隔;如果没有“~”符,开始用“~”分隔。不管有没有"~"符,都循环分隔
                            {
                                for (int b = 0; b < sComponents.Length; b++)
                                {
                                    XmlElement componentEl = _xmlDoc.CreateElement(sFields[0] + "." + a.ToString() + "." + b.ToString());

                                    //通过"^"分隔
                                    string[] subComponents = GetComponents(sComponents[b]);
                                    if (subComponents.Length > 1)//2.如果有字组,大部分是没有的
                                    {
                                        for (int c = 0; c < subComponents.Length; c++)
                                        {
                                            //修改了一个错误
                                            string[] subComponentRepetitions = GetSubComponents(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.GetSubComponents(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
                        {
                            //0:如果不可以分隔,可以直接写节点值了。
                            fieldEl.InnerText = sFields[a];
                            el.AppendChild(fieldEl);
                        }
                    }
                }
            }



            return _xmlDoc;
        }

        
        
        //测试方法转XML
        //string sHL7asXml = PT.Common.HL7ToXmlConverter.ConvertToXml(hl7Data);
        //ThreadUPtextBoxMsg(textBoxMsgAppendText, "\r\n[解析HL7消息]" + sHL7asXml);
        XmlDocument xmlObject = PT.Common.HL7ToXmlConverter.ConvertToXmlObject(hl7Data);
        String chuang1 = PT.Common.HL7ToXmlConverter.GetText(xmlObject, "PV1/PV1.6/PV1.6.0/PV1.6.0.2", 0);
        String chuang2 = PT.Common.HL7ToXmlConverter.GetText(xmlObject, "PV1/PV1.3/PV1.3.0/PV1.3.0.2", 0);
        ThreadUPtextBoxMsg(textBoxMsgAppendText, "\r\n[解析HL7消息为XML]" + name + "从" + chuang1 + "床换到" + chuang2 + "床");
        
    }

}

  

解析后的XML,可读性比较差。

 

C#格式化XML的代码:

        /// <summary>
        /// 格式化XML(C#版)
        /// </summary>
        /// <param name="sUnformattedXml"></param>
        /// <returns></returns>
        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();
        }

  

以上是关于HL7 2.6解析转XML(C#版)的主要内容,如果未能解决你的问题,请参考以下文章

HL7 服务器和 HL7 监听器

转:HL7 Tools suite

HL7 转换为XML的事例

从 XML 声明片段获取 XML 编码:部分内容解析不支持 XmlDeclaration

如何读取HL7文件并使用Apache Camel,Hapi和Spring(Java配置)解析它

在 C# 代码中解析(大)XML 的最佳方法是啥?