Introduction
Refer to http://www.codeproject.com/Articles/29670/Converting-HL-to-XML.
Background
Noticed that the code in the above article does not account for repetitions correctly? The XML generated from the code does not correctly assign node numbers to the repeated fields.
I modified the above code to account for repeated fields and correctly assign the node numbers.
Using the Code
Refer to the above article for the purpose and brief description.
Tools like HL7Spy show the repeated fields as 'PID-11[2].1' , 'PID-12[3].3' etc.
But, while converting an HL7 message to XML, such notation cannot be used.
XML does not allow for special characters like '[' and ']' to be used in node names.
Therefore, the code below maps repeated fields in the XML using '_' instead of '[ ]'.
For example, the above two fields will be represented as 'PID-11_2.1' and 'PID-12_3.3'.
Using the Code
string sHL7asXml = HL7ToXmlConverter.ConvertToXml(myHL7string);
Full class is as given below:
public static class HL7ToXmlConverter
{
private static XmlDocument _xmlDoc;
private static char _fieldSeparator;
private static char _componentSeparator;
private static char _subComponentSeparator;
private static char _repetitionSeparator;
private static char _escapeCharacter = '\\';
public static string ConvertToXml(string sHL7, string validationType)
{
_xmlDoc = CreateXmlDoc();
char[] delimiter = { '\r', '\n' };
string[] sHL7Lines = sHL7.Split(delimiter);
int j = -1;
for (int i = 0; i < sHL7Lines.Length; i++)
{
j = sHL7Lines[i].IndexOf(@"<");
}
_fieldSeparator = sHL7Lines[0][3];
_componentSeparator = sHL7Lines[0][4];
_subComponentSeparator = sHL7Lines[0][7];
_repetitionSeparator = '~';
string encodingCharacters = GetEncodingCharacters
(_componentSeparator, _repetitionSeparator, _escapeCharacter, _subComponentSeparator);
for (int i = 0; i < sHL7Lines.Length; i++)
{
if (sHL7Lines[i] != string.Empty)
{
string sHL7Line = sHL7Lines[i];
string[] sFields;
if (i == 0)
{
sFields = HL7ToXmlConverter.GetMessageFieldsForMSH(sHL7Line);
}
else
{
sFields = HL7ToXmlConverter.GetMessgeFields(sHL7Line);
}
if ((sFields[0] == "OBX" && validationType == "Syndromic Surveillance")
|| (sFields[0] == "OBX" && validationType == "Immunization"))
{
sFields[0] = sFields[0] + "-" + GetComponents(sFields[3])[0];
}
if (sFields[0] == "OBX" && validationType == "Lab")
{
}
XmlElement el = _xmlDoc.CreateElement(sFields[0]);
_xmlDoc.DocumentElement.AppendChild(el);
for (int a = 0; a < sFields.Length; a++)
{
if (sFields[a] != encodingCharacters)
{
string[] fieldRepetitions = GetRepetitions(sFields[a]);
if (fieldRepetitions.Length > 1)
{
for (int d = 0; d < fieldRepetitions.Length; d++)
{
if (d == 0)
{
XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] +
"-" + a.ToString());
string[] sComponents = HL7ToXmlConverter.GetComponents
(fieldRepetitions[d]);
if (sComponents.Length > 1)
{
for (int b = 0; b < sComponents.Length; b++)
{
XmlElement componentEl = _xmlDoc.CreateElement
(sFields[0] + "-" + a.ToString() +
"." + (b + 1).ToString());
string[] subComponents =
GetSubComponents(sComponents[b]);
if (subComponents.Length > 1)
{
for (int c = 0; c < subComponents.Length; c++)
{
XmlElement subComponentEl =
_xmlDoc.CreateElement(sFields[0] + "-" +
a.ToString() + "." +
(b + 1).ToString() + "." + (c + 1).ToString());
subComponentEl.InnerText = subComponents[c];
componentEl.AppendChild(subComponentEl);
}
fieldEl.AppendChild(componentEl);
}
else
{
componentEl.InnerText = sComponents[b];
fieldEl.AppendChild(componentEl);
el.AppendChild(fieldEl);
}
}
el.AppendChild(fieldEl);
}
else
{
fieldEl.InnerText = fieldRepetitions[d];
el.AppendChild(fieldEl);
}
}
else
{
XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] +
"-" + a.ToString() + "_" + (d + 1).ToString());
string[] sComponents = HL7ToXmlConverter.GetComponents
(fieldRepetitions[d]);
if (sComponents.Length > 1)
{
for (int b = 0; b < sComponents.Length; b++)
{
XmlElement componentEl = _xmlDoc.CreateElement
(fieldEl.Name + "." + (b + 1).ToString());
string[] subComponents = GetSubComponents
(sComponents[b]);
if (subComponents.Length > 1)
{
for (int c = 0; c < subComponents.Length; c++)
{
XmlElement subComponentEl =
_xmlDoc.CreateElement(componentEl.Name +
"." + (c + 1).ToString());
subComponentEl.InnerText = subComponents[c];
componentEl.AppendChild(subComponentEl);
}
fieldEl.AppendChild(componentEl);
}
else
{
componentEl.InnerText = sComponents[b];
fieldEl.AppendChild(componentEl);
el.AppendChild(fieldEl);
}
}
el.AppendChild(fieldEl);
}
else
{
fieldEl.InnerText = fieldRepetitions[d];
el.AppendChild(fieldEl);
}
}
}
}
else
{
XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] + "-" +
a.ToString());
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 + 1).ToString());
string[] subComponents = GetSubComponents(sComponents[b]);
if (subComponents.Length > 1)
{
for (int c = 0; c < subComponents.Length; c++)
{
XmlElement subComponentEl =
_xmlDoc.CreateElement(sFields[0] + "-" +
a.ToString() + "." +
(b + 1).ToString() + "." + (c + 1).ToString());
subComponentEl.InnerText = subComponents[c];
componentEl.AppendChild(subComponentEl);
}
fieldEl.AppendChild(componentEl);
}
else
{
componentEl.InnerText = sComponents[b];
fieldEl.AppendChild(componentEl);
el.AppendChild(fieldEl);
}
}
el.AppendChild(fieldEl);
}
else
{
fieldEl.InnerText = sFields[a];
el.AppendChild(fieldEl);
}
}
}
else
{
XmlElement fieldEl = _xmlDoc.CreateElement(sFields[0] + "-" + a.ToString());
fieldEl.InnerText = sFields[a];
el.AppendChild(fieldEl);
}
}
}
}
return _xmlDoc.OuterXml;
}
private static string[] GetMessageFieldsForMSH(string s)
{
string[] sFieldsPlaceHolder = HL7ToXmlConverter.GetMessgeFields(s);
string[] sFieldsForMSG = new string[sFieldsPlaceHolder.Length + 1];
sFieldsForMSG[0] = sFieldsPlaceHolder[0];
sFieldsForMSG[1] = "|";
for (int x = 2; x < sFieldsForMSG.Length; x++)
{
sFieldsForMSG[x] = sFieldsPlaceHolder[x - 1];
}
return sFieldsForMSG;
}
public static string GetEncodingCharacters(char componentSeparator,
char repetitionSeparator, char escapeCharacter, char subComponentSeparator)
{
char[] arr = new char[4];
arr[0] = componentSeparator;
arr[1] = repetitionSeparator;
arr[2] = escapeCharacter;
arr[3] = subComponentSeparator;
return new string(arr);
}
private static string[] GetMessgeFields(string s)
{
return s.Split(_fieldSeparator);
}
private static string[] GetComponents(string s)
{
return s.Split(_componentSeparator);
}
private static string[] GetSubComponents(string s)
{
return s.Split(_subComponentSeparator);
}
private static string[] GetRepetitions(string s)
{
return s.Split(_repetitionSeparator);
}
private static XmlDocument CreateXmlDoc()
{
XmlDocument output = new XmlDocument();
XmlElement rootNode = output.CreateElement("HL7Message");
output.AppendChild(rootNode);
return output;
}
}