HL7 消息解析库:C 语言实现
HL7 消息解析库:C 语言实现
本 C 语言库提供了一套完整的 HL7 消息解析、构建、修改和打印功能。它支持多种 HL7 版本,并提供丰富的接口函数,方便开发者对 HL7 消息进行灵活的操作。
库的功能
- 解析: 将 HL7 消息字符串解析成结构化的数据。
- 构建: 将结构化的数据构建成 HL7 消息字符串。
- 修改: 对 HL7 消息中的特定字段进行修改和添加。
- 打印: 以人类可读的方式打印 HL7 消息内容。
代码示例
#include "hl7.h"
#include <string.h>
char *
concat(char *string1, char *string2){
int length1, length2;
length2 = strlen(string2);
if (length2==0)
return string1;
length1 = strlen(string1);
if (string1 = (char *) realloc(string1, length1 + length2 +1)){
strncpy(&string1[length1], string2, length2);
string1[length1 + length2] = '\000';
return string1;
} else {
exit(1);
}
}
char *
strset (char *string)
{
char *pointer_to_string;
if (pointer_to_string = (char *) malloc (strlen (string)+1))
{
strcpy (pointer_to_string, string);
return (pointer_to_string);
}
else
{
/* die */
exit (1);
}
}
/* end strset */
void hl7count (struct hl7_part_t *message, char *seg_location) {
} /* end hl7count */
void hl7rawcount (struct hl7_part_t *message, char *location) {
} /* end hl7rawcount */
void hl7delete (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7delete */
void hl7insert (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7insert */
void hl7rawdelete (struct hl7_part_t *message, struct hl7_location_t *location){
} /* end hl7rawdelete */
void hl7rawinsert (struct hl7_part_t *message, struct hl7_location_t *location, char *string){
} /* end hl7rawinsert */
void hl7set (struct hl7_part_t *message, char *seg_location, char *string){
} /* end hl7set */
void hl7get (struct hl7_part_t *message, char *seg_location){
} /* end hl7get */
void hl7rawset (struct hl7_part_t *message, struct hl7_location_t *location, char *string){
/* this one is a little harder, you have to traverse the string to the given
location, creating missing nodes as you go and then set the final portion
to the given string. */
} /* end hl7rawset */
char *hl7rawget (struct hl7_part_t *message, struct hl7_location_t *given_location){
struct hl7_part_t *hl7_part;
struct hl7_location_t *location;
char *msg_string; /* points to the message string */
char separators[8]; /* list of separators in proper order */
int i,
depth = 0;
/* initialize the pointer to the string that is returning the value */
msg_string = strset("");
/* Traverse the tree */
hl7_part = message->lower;
for (location = given_location ; location->next ; location=location->next){
/*next for the count */
for(i=location->count; i ; i--) {
if(hl7_part->next){
hl7_part=hl7_part->next;
} else {
return msg_string;
}
}
/* lower each level */
if(hl7_part->lower){
depth++;
hl7_part=hl7_part->lower;
} else {
/*
return msg_string;
*/
}
}
/* this needs to be a subroutine because we just did it twice */
/* build the seperators string */
separators[0] = '\n';
separators[1] = '\n';
separators[2] = '\r';
separators[3] = message->lower->lower->lower->next->lower->lower->lower->data[0];
separators[4] = message->lower->lower->lower->next->next->lower->lower->lower->data[3];
separators[5] = message->lower->lower->lower->next->next->lower->lower->lower->data[0];
separators[6] = message->lower->lower->lower->next->next->lower->lower->lower->data[1];
separators[7] = '\000';
printf("The depth is >%d<
", depth);
hl7printlocation(given_location);
/* Call the join function, */
msg_string=join(hl7_part, msg_string, &separators[depth+1]);
/* return the string that we found */
return msg_string;
} /* end hl7rawget */
char *join (struct hl7_part_t *hl7_part, char *msg_string, char *separators){
char current_separator[2];
if (separators=='\000')
exit(1);
current_separator[0] = separators[0];
current_separator[1] = '\000';
if (hl7_part->data){
msg_string = concat(msg_string, hl7_part->data);
}
if (hl7_part->lower){
msg_string = join(hl7_part->lower, msg_string, &separators[1]);
}
if (hl7_part->next){
msg_string = concat(msg_string, current_separator);
msg_string = join(hl7_part->next, msg_string, separators);
}
return msg_string;
} /* end join */
char *hl72str (struct hl7_part_t *message){
char separators[8]; /* list of separators in proper order */
char *msg_string; /* points to the message string */
int length;
msg_string=strset("");
/* build the seperators string */
separators[0] = '\n';
separators[1] = '\n';
separators[2] = '\r';
separators[3] = message->lower->lower->lower->next->lower->lower->lower->data[0];
separators[4] = message->lower->lower->lower->next->next->lower->lower->lower->data[3];
separators[5] = message->lower->lower->lower->next->next->lower->lower->lower->data[0];
separators[6] = message->lower->lower->lower->next->next->lower->lower->lower->data[1];
separators[7] = '\000';
/* turn the message into a string */
msg_string = join(message, msg_string, separators);
/* fix the field separator field */
length=strlen(msg_string);
strncpy(&msg_string[4], &msg_string[6], length-5);
if (!(msg_string=(char *) realloc(msg_string, length-2))){
/* not enough memory, die */
exit(1);
}
return msg_string;
} /* end hl72str */
struct hl7_part_t *split (struct hl7_part_t *hl7_part, char *separators)
{
struct hl7_part_t *head, /* begining of the data list */
*current; /* tail of the data list */
int begin = 0, /* start of the current string */
scan = 0; /* current position in string */
/* if the list of separators is empty, we have reached a leaf, return null */
if (separators[0] == '\000'){
return (struct hl7_part_t *) 0;
}
/* setup structure for current level of operations */
if (!(current = head = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t))))
exit (1);
/* initialize the structure to some sane values */
current->data = (char *) 0;
current->next = (struct hl7_part_t *) 0;
current->lower = (struct hl7_part_t *) 0;
/* start looking thru the string for current seperator */
for (; hl7_part->data[scan]; scan++)
{
/* when we find the current seperator */
if (hl7_part->data[scan] == separators[0])
{
/* replace the seperator with a NULL */
hl7_part->data[scan] = '\000';
/* set a copy of the string that we found to current data element */
current->data = strset (&hl7_part->data[begin]);
/* split the string into substrings */
/* this is a little tricky */
/* I send the seperator string starting with its _second_ element */
current->lower = split (current, &separators[1]);
/* setup for the next string that we find */
if (!(current->next = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t))))
exit (1);
/* move the current pointer to the node that we just created */
current = current->next;
/* initialize the data to some sane values */
current->data = (char *) 0;
current->next = (struct hl7_part_t *) 0;
current->lower = (struct hl7_part_t *) 0;
/* set the begining of the string to follow the found string */
begin = scan + 1;
}
}
/* We reached the end of the string without finding (another) seperator.
But there is still a string that we need to take care of. */
/* put a copy of the string in the current data element */
current->data = strset (&hl7_part->data[begin]);
/* split the data element into substrings */
/* this is a little tricky */
/* I send the seperator string starting with its _second_ element */
current->lower = split (current, &separators[1]);
/* get rid of the string from the parent, we stored it safely at this level */
free (hl7_part->data);
/* set the parent data element to the null pointer so that it won't be
pointing to the place where the string used to be. */
hl7_part->data = (char *) 0;
/* return the list of substrings found to the parent. */
return head;
} /* end split */
struct hl7_part_t *str2hl7 (char *message_string)
{
struct hl7_part_t *message; /* Message structure that we are working on */
char delimiters[6], /* list of delimiters from the message */
separators[7], /* list of separators in proper order */
temp[6]; /* used to set the correct delimiters
in the final message structure */
/* probably should check that the message begins with MSH
and is longer than a minimum length... */
if (!(message = (struct hl7_part_t *) malloc (sizeof (struct hl7_part_t)))){
/* If we don't have enough memory, quit.
/* This is kind of abrupt and needs to be more elegant. */
exit (1);
}
/* put some sane values into the clean new structure */
message->lower=(struct hl7_part_t *)0;
message->next=(struct hl7_part_t *)0;
/* put a copy of hl7_string into the proper place in the message structure */
message->data = strset (message_string);
/* copy the hl7 delimiters to a string to hold them for processing */
strncpy (delimiters, &message->data[3], 5);
/* close the end of the string with a terminator so that we don't dump core */
delimiters[5] = '\000';
/* reorder the delimiters into the proper order for seperation */
separators[0] = '\n';
separators[1] = '\r';
separators[2] = delimiters[0];
separators[3] = delimiters[1];
separators[4] = delimiters[2];
separators[5] = delimiters[4];
separators[6] = '\000';
/* remove the delimiters from the message so that we don't get confused */
message->data[4] = 'X';
message->data[5] = '|';
message->data[6] = 'Z';
message->data[7] = 'K';
/* recursively call split to split the message on each seperator */
message->lower = split (message, separators);
free (message->lower->lower->lower->next->lower->lower->lower->data);
strncpy (temp, &delimiters[0], 1);
temp[1] = '\000';
message->lower->lower->lower->next->lower->lower->lower->data = strset (temp);
free (message->lower->lower->lower->next->next->lower->lower->lower->data);
strncpy (temp, &delimiters[1], 4);
temp[4] = '\000';
message->lower->lower->lower->next->next->lower->lower->lower->data = strset (temp);
/* we are done, return the results */
return message;
} /* end str2hl7 */
void hl7printlocation(struct hl7_location_t *location){
for(; location->next; location=location->next) {
printf("%d", location->count);
if (location->next->next){
printf(".");
}
}
} /* end hl7printlocation */
void hl7rawprint(struct hl7_part_t *hl7_part, struct hl7_location_t *location,
struct hl7_location_t * current, int state)
{
/* recursively traverse the tree, keep track of where you are and print out the data */
if (!(current->next)){
if (!(current->next = (struct hl7_location_t *)
malloc(sizeof(struct hl7_location_t)))){
exit (1);
}
current->next->next = (struct hl7_location_t *) 0;
current->next->count = 0;
}
if ((hl7_part->data) &&(strlen(hl7_part->data))){
hl7printlocation(location);
printf(" >%s<
", hl7_part->data);
}
if (hl7_part->lower){
hl7rawprint(hl7_part->lower, location, current->next, LOWER);
}
if (hl7_part->next){
current->count++;
hl7rawprint(hl7_part->next, location, current, NEXT);
}
if (state==LOWER)
current->count=0;
return;
} /* end hl7rawprint */
void hl7print (struct hl7_part_t *message)
{
struct hl7_location_t *location;
/* setup some data structures and call the real function */
if (!(location = (struct hl7_location_t *) malloc(sizeof(struct hl7_location_t)))){
exit (1);
}
location->count = 0;
location->next = (struct hl7_location_t *) 0;
hl7rawprint(message->lower, location, location, BEGIN);
hl7freelocation(location);
/* need to free the memory that was allocated for the location! */
} /* end hl7print */
void hl7freelocation(struct hl7_location_t *location){
/* if we aren't at the end of the list, */
/* move to the next element in the list */
if(location->next)
hl7freelocation(location->next);
/* free the current element of the list */
free(location);
/* return to the previous element in the list */
return ;
} /* hl7freelocation */
void hl7free (struct hl7_part_t *hl7_part)
{
/* free data, if it is present */
if (hl7_part->data){
free(hl7_part->data);
}
/* look in each lower branch first, if present */
if (hl7_part->lower)
{
hl7free (hl7_part->lower);
}
/* then look in each next branch, if present */
if (hl7_part->next)
{
hl7free (hl7_part->next);
}
/* free the current node */
free(hl7_part);
/* return to previous node */
return;
} /* end hl7free */
使用方法
- 将代码复制到您的项目中。
- 在您的代码中包含
hl7.h头文件。 - 使用提供的接口函数对 HL7 消息进行操作。
注意事项
- 本库使用 C 语言编写,需要在支持 C 语言的平台上使用。
- 本库假设 HL7 消息格式正确,对于格式错误的消息可能无法正常解析或构建。
- 本库未提供对 HL7 消息的完整验证功能,开发者需要自行进行验证。
联系方式
如果您在使用本库过程中遇到任何问题,请联系:
- 邮箱:your_email@example.com
- 网站:your_website.com
希望本库能帮助您更好地处理 HL7 消息!
原文地址: https://www.cveoy.top/t/topic/npgx 著作权归作者所有。请勿转载和采集!