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 */



使用方法

  1. 将代码复制到您的项目中。
  2. 在您的代码中包含 hl7.h 头文件。
  3. 使用提供的接口函数对 HL7 消息进行操作。

注意事项

  • 本库使用 C 语言编写,需要在支持 C 语言的平台上使用。
  • 本库假设 HL7 消息格式正确,对于格式错误的消息可能无法正常解析或构建。
  • 本库未提供对 HL7 消息的完整验证功能,开发者需要自行进行验证。

联系方式

如果您在使用本库过程中遇到任何问题,请联系:

  • 邮箱:your_email@example.com
  • 网站:your_website.com

希望本库能帮助您更好地处理 HL7 消息!

HL7 消息解析库:C 语言实现

原文地址: https://www.cveoy.top/t/topic/npgx 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录