Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help Parsing a Text File

Status
Not open for further replies.

thechimota

Programmer
Oct 6, 2005
5
US
Hello everyone,

I am trying to write a smal application to parse a text file (HL7 format) and I am having major trouble. The input file looks sort of like:

MSH|^~\&|LIS|RC|HIS||20070405233331||ORU^R01|20021353108535|
PID|||123456||test^patient^||19840515|F||||||||||1234567|
PV1||O|LB^|
ORC|RE|
OBR||8971795|H8632^LIS|MPB^METABOLIC PANEL
OBX|1|NM|XNA^SODIUM|1.1|140|mmol/L|||||F||
MSH|^~\&|LIS|RC|HIS||20070405233331||ORU^R01|20021353108535|
PID|||234567||test^patient2^||19840515|F||||||||||234567|
PV1||O|LB^|
ORC|RE|
OBR||8971795|H8632^LIS|MPB^METABOLIC PANEL
OBX|1|NM|XNA^SODIUM|2.1|140|mmol/L|||||F||

I am trying to parse the file to be read into a MS Access database for further manipulation.

The output needs to look like

123456,04/05/1984,F,LB,H8632,LIS,MPB,METABLOLIC PANEL,
123456,04/05/1984,F,NM,XNA,SODIUM,1.1,140,mmol/L,
234567,04/05/1984,F,LB,H8632,LIS,MPB,METABLOLIC PANEL,
234567,04/05/1984,F,NM,XNA,SODIUM,2.1,140,mmol/L,

This is a very small sample but it is just for the idea. There is one message header then detail several time thoughout the file. Any help on how to read in the file and parse would help. This is my second time writing a parse app for HL7 files but the first only had to parse one patient per file. I am just not sure how to define the code to do more.

Any info will help. Thanks
 
The data seem to be pipe-delimited. Use the String.Split() method to split the data on the pipe character into a string array. After that, the rest should be easy...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Thanks Steve,

The part that has me confused is that I will need to keep the medical record number consistant with the patent for each line until a new patient occurs. I know the sample is modified in the begining but 123456 will have multiple lines under it without including the number as will the rest of the records. The class I am trying to modify looks like this:

public static string ParseFile(string FilePath)
{
StreamReader re = File.OpenText(FilePath);
string input = re.ReadToEnd();
re.Close();
string[] tmp = input.Split(Chr(13));
string[] pid_line = null;
string[] orc_line = null;


ArrayList notes = new ArrayList();
foreach(string str in tmp)
{
if(str.Length>2)
{
string linecode = str.Substring(0,3);
switch(linecode)
{
case "PID":
pid_line = str.Split('|');
break;
case "ORC":
orc_line = str.Split('|');
break;
}
}
}

//now parse for the OBR/OBX
Hashtable OBRList = new Hashtable();

Hashtable ht = null;
foreach(string str in tmp)
{
if(str.Length>2)
{
string linecode = str.Substring(0,3);
switch(linecode)
{
case "OBR":
ht = new Hashtable();
string[] t = str.Split('|');
OBRList.Add(t,ht);
break;
case "OBX":
string[] n = str.Split('|');
ht.Add(n[1],n);
break;

}
}
}

//Additional parsing of subfields
string[] dr_field = orc_line[12].Split('^');


//fields
string RequestNumber = orc_line[2];
string OrderingPhysicianID = dr_field[0];
string OrderingPhysicianLN = dr_field[1];
string OrderingPhysicianFN = dr_field[2];
string OrderingPhysicianMI = dr_field[3];

string ChartNumber = pid_line[2];


StringBuilder sb = new StringBuilder();
foreach(string[] obr_line in OBRList.Keys)
{

string[] obr_fields = obr_line[4].Split('^');
Hashtable obxHT = OBRList[obr_line] as Hashtable;
foreach(string[] obx_line in obxHT.Values)
{
string[] obx_fields = obx_line[3].Split('^');

string OBRNumber = obr_line[1];
string GeneralTestType = obr_fields[0];
string GeneralTestDesc = obr_fields[1];

string SpecificTestNumber = obx_fields[0];
string SpecificTestDesc = obx_fields[1];
string TestResult = obx_line[5];
string TestUnit = obx_line[6];
string TestNormalResult = obx_line[7];
string TestAbnormalFlag = obx_line[8];
string TestProbability = obx_line[9];
string TestNature = obx_line[10];

//parse out the date
string year = obx_line[14].Substring(0,4);
string month = obx_line[14].Substring(4,2);
string day = obx_line[14].Substring(6,2);
string TestDate = month + "/" + day + "/" + year;


sb.Append(ChartNumber + ";" + RequestNumber + ";" + OrderingPhysicianID + ";");
sb.Append(OrderingPhysicianLN + ";" + OrderingPhysicianFN + ";" + OrderingPhysicianMI + ";");
sb.Append(OBRNumber + ";" + GeneralTestType + ";" + GeneralTestDesc + ";" + SpecificTestNumber + ";");
sb.Append(SpecificTestDesc + ";" + TestResult + ";" + TestUnit + ";" + TestNormalResult + ";");
sb.Append(TestAbnormalFlag + ";" + TestProbability + ";" + TestNature + ";" + TestDate + ";");
bool first = true;
foreach(string note in notes)
{
if(note.Length>2)
{
if(first)
{
sb.Append(note);
first=false;
}
else
sb.Append("~" + note);
}
}
sb.Append("\r\n");
}
}
return sb.ToString();
}

private static Char Chr(int i)
{
//Return the character of the given character value
return Convert.ToChar(i);
}

private static int Asc(char[] ch)
{
//Return the character value of the given character
return (int)Encoding.ASCII.GetBytes(ch)[0];
}
}
}

This only will work if one patient record is submited. Now that I am working with multiple per file, I feel I need some kind of iteration to capture each of the next records.
I know it is long and I am not trying let anyone do the work for me, I just feel I am missing something.

Again, any help would be appreciated.

Thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top