将 HL7 转换为 XML
一个初步尝试,用于将 HL7 转换为 XML 的类。欢迎贡献。
引言
对于我们这些不幸需要处理它的人来说,HL7 是一种医疗系统之间常用的通信语言。它是在 XML 发明之前,有人梦寐以求创造出来的。事实上,HL7 的最新版本就是 XML。然而,对于那些仍然需要使用旧系统的人来说,它是一种笨拙且不友好的语言,消息组件使用回车符、管道符、波浪线和井号分隔。
由于大多数应用程序使用 XML 进行数据交换,而且 XML 无论如何都更容易处理,因此如果有一个可免费获得的 HL7 到 XML 转换库将会很有帮助。遗憾的是,尽管我在网上搜索了很久,但我没有找到一个可以轻松集成到应用程序中的(免费)类或实用程序。有一些 Java 库,还有一个著名的(优秀的)商业应用程序,但没有免费且易于使用的。
本文是我的尝试创建这样一个库的 v1 版本。请随意使用和扩展它——最重要的是,修复我遗漏的任何错误。
使用代码
一个非常简单的 HL7 消息如下所示
MSH|^~\&|||||20080925161613||ADT^A05||P|2.6
这个类和方法只是生成相同消息的 XML 表示形式。请注意,这个类不够聪明,无法知道它正在转换的 HL7 消息类型——它只是创建了它的 XML 版本。关键在于,然后你可以使用 XPath 来检索你想要使用的段,因为你知道它的位置。该方法返回的上述 HL7 消息如下所示
<HL7Message>
<MSH>
<MSH.0>MSH</MSH.0>
<MSH.1>^~\&</MSH.1>
<MSH.2/>
<MSH.3/>
<MSH.4/>
<MSH.5/>
<MSH.6>20080925161613</MSH.6>
<MSH.7/>
<MSH.8>
<MSH.8.0>ADT</MSH.8.0>
<MSH.8.1>A05</MSH.8.1>
</MSH.8>
<MSH.9/>
<MSH.10>P</MSH.10>
<MSH.11>2.6</MSH.11>
</MSH>
</HL7Message>
这是一个静态类,它返回一个 XML 字符串(作为一个字符串;它可以很容易地修改为返回一个 XmlDocument
)。
使用该类
string sHL7asXml = HL7ToXmlConverter.ConvertToXml(myHL7string);
完整的类如下所示
/// This class takes an HL7 message
/// and transforms it into an XML representation.
public static class HL7ToXmlConverter
{
// This is the XML document we'll be creating
private static XmlDocument _xmlDoc;
/// <summary>
/// Converts an HL7 message into an XML representation of the same message.
/// </summary>
/// <param name="sHL7">The HL7 to convert</param>
/// <returns></returns>
public static string ConvertToXml(string sHL7)
{
// Go and create the base XML
_xmlDoc = CreateXmlDoc();
// HL7 message segments are terminated by carriage returns,
// so to get an array of the message segments, split on carriage return
string[] sHL7Lines = sHL7.Split('\r');
// Now we want to replace any other unprintable control
// characters with whitespace otherwise they'll break the XML
for (int i = 0; i < sHL7Lines.Length; i++)
{
sHL7Lines[i] = Regex.Replace(sHL7Lines[i], @"[^ -~]", "");
}
/// Go through each segment in the message
/// and first get the fields, separated by pipe (|),
/// then for each of those, get the field components,
/// separated by carat (^), and check for
/// repetition (~) and also check each component
/// for subcomponents, and repetition within them too.
for (int i = 0; i < sHL7Lines.Length; i++)
{
// Don't care about empty lines
if (sHL7Lines[i] != string.Empty)
{
// Get the line and get the line's segments
string sHL7Line = sHL7Lines[i];
string[] sFields = HL7ToXmlConverter.GetMessgeFields(sHL7Line);
// Create a new element in the XML for the line
XmlElement el = _xmlDoc.CreateElement(sFields[0]);
_xmlDoc.DocumentElement.AppendChild(el);
// For each field in the line of HL7
for (int a = 0; a < sFields.Length; a++)
{
// Create a new element
XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] +
"." + a.ToString());
/// Part of the HL7 specification is that part
/// of the message header defines which characters
/// are going to be used to delimit the message
/// and since we want to capture the field that
/// contains those characters we need
/// to just capture them and stick them in an element.
if (sFields[a] != @"^~\&")
{
/// Get the components within this field, separated by carats (^)
/// If there are more than one, go through and create an element for
/// each, then check for subcomponents, and repetition in both.
string[] sComponents = HL7ToXmlConverter.GetComponents(sFields[a]);
if (sComponents.Length > 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)
// There were subcomponents
{
for (int c = 0; c < subComponents.Length; c++)
{
// Check for repetition
string[] subComponentRepetitions =
GetRepetitions(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 // There were no subcomponents
{
string[] sRepetitions =
HL7ToXmlConverter.GetRepetitions(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
{
fieldEl.InnerText = sFields[a];
el.AppendChild(fieldEl);
}
}
else
{
fieldEl.InnerText = sFields[a];
el.AppendChild(fieldEl);
}
}
}
}
return _xmlDoc.OuterXml;
}
/// <summary>
/// Split a line into its component parts based on pipe.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private static string[] GetMessgeFields(string s)
{
return s.Split('|');
}
/// <summary>
/// Get the components of a string by splitting based on carat.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private static string[] GetComponents(string s)
{
return s.Split('^');
}
/// <summary>
/// Get the subcomponents of a string by splitting on ampersand.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private static string[] GetSubComponents(string s)
{
return s.Split('&');
}
/// <summary>
/// Get the repetitions within a string based on tilde.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private static string[] GetRepetitions(string s)
{
return s.Split('~');
}
/// <summary>
/// Create the basic XML document that represents the HL7 message
/// </summary>
/// <returns></returns>
private static XmlDocument CreateXmlDoc()
{
XmlDocument output = new XmlDocument();
XmlElement rootNode = output.CreateElement("HL7Message");
output.AppendChild(rootNode);
return output;
}
}
关注点
这是我在 The Code Project 上的第一篇文章。HL7 的新版本(一直应该用 XML 编写)将使这个类变得多余,但我希望在此期间它对人们有用。
我讨厌 HL7!:-)
历史
目前还没有历史记录。