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