/********************************************************/ /* Xml_Read_File - Example */ /********************************************************/ Xml_object *Xml_Read_File( char *fname ) { FILE *infile; int lnn=0; char *tag, *attrib, *value, *contents; Xml_object *newtag, *roottag=0; Xml_name_value_pair *newattrib, *lastattrib; struct xml_private_stack *current_parent, *old_tag; /* Current_parent points to parent of current children. */ infile = fopen(fname,"r"); if (infile==0) {printf("XML Error: Cannot open input file '%s'.\n",fname); return 0;} current_parent = new_xml_stack_item(0,0); /* Set the root tag level. */ tag = (char *)malloc(XML_MAX_STRLEN); attrib = (char *)malloc(XML_MAX_STRLEN); value = (char *)malloc(XML_MAX_STRLEN); contents = (char *)malloc(XML_MAX_STRLEN); xml_parse( infile, tag, contents, XML_MAX_STRLEN, &lnn ); while (!feof(infile)) { /*next_tag*/ xml_grab_tag_name( tag, attrib, XML_MAX_STRLEN ); if (attrib[0]=='/') /* If tag begins with "/", then go-up (pop-stack after comparing tag). */ { /*pop-stack*/ if ((current_parent->current_object==0) || (strcasecmp(current_parent->current_object->tag,&(attrib[1]))!=0)) {printf("Xml Error: Mismatching closing tag '%s'. Aborting.\n",attrib); free(tag); free(attrib); free(value); free(contents); return 0;} old_tag = current_parent; current_parent = current_parent->parent; xml_private_free_stack_item( old_tag ); if (current_parent==0) {printf("Xml Error: extra closing tag '%s'. Aborting.\n",attrib); free(tag); free(attrib); free(value); free(contents); return 0;} } /*pop-stack*/ else { /*Open-tag*/ newtag = new_xml_object( attrib, contents ); if (roottag == 0) roottag = newtag; else { if (current_parent->last_child == 0) current_parent->current_object->children = newtag; else current_parent->last_child->nxt = newtag; newtag->parent = current_parent->current_object; } current_parent->last_child = newtag; xml_grab_attrib( tag, attrib, value, XML_MAX_STRLEN ); /* Accept the attributes within tag. */ while ((attrib[0]!='\0') && (attrib[0]!='/') && (attrib[0]!='?')) { newattrib = new_xml_attribute( attrib, value ); if (newtag->attributes==0) newtag->attributes = newattrib; else lastattrib->nxt = newattrib; lastattrib = newattrib; xml_grab_attrib( tag, attrib, value, XML_MAX_STRLEN ); } /* If tag does not end in "/", then go-down (push-stack). IE. Next tag should be a child of present tag. */ if (attrib[0]!='/') { current_parent = new_xml_stack_item( current_parent, newtag ); } /* Otherwise, attaches to last child of present parent. */ } /*Open-tag*/ xml_parse( infile, tag, contents, XML_MAX_STRLEN, &lnn ); } /*next_tag*/ fclose(infile); while (xml_stack_freelist != 0) /* Cleanup temporary variables. */ { current_parent = xml_stack_freelist; xml_stack_freelist = xml_stack_freelist->parent; free(current_parent); } free(tag); free(attrib); free(value); free(contents); return roottag; }