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