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