Generated from xml_element.c with ROBODoc v3.2.3 on Sat Sep 29 16:00:40 2001

TABLE OF CONTENTS

  1. ABOUT/xml_element
  2. xml_element/xml_elem_free
  3. xml_element/xml_elem_free_non_recurse
  4. xml_element/xml_elem_new
  5. xml_element/xml_elem_parse_buf
  6. xml_element/xml_elem_serialize_to_stream
  7. xml_element/xml_elem_serialize_to_string

ABOUT/xml_element

NAME
   xml_element
AUTHOR
   Dan Libby, aka danda  (dan@libby.com)
CREATION DATE
   06/2000
HISTORY
   $Log: xml_element.c.html,v $
   Revision 1.2  2001/09/29 22:06:29  danda
   updated api docs
   Revision 1.5  2001/09/29 21:58:05  danda
   adding cvs log to history section

   10/15/2000 -- danda -- adding robodoc documentation
TODO
   Nicer external API. Get rid of macros.  Make opaque types, etc.
PORTABILITY
   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
   about anything with minor mods.
NOTES
   This code incorporates ideas from expat-ensor from http://xml.ensor.org.
  
   It was coded primarily to act as a go-between for expat and xmlrpc. To this
   end, it stores xml elements, their sub-elements, and their attributes in an
   in-memory tree.  When expat is done parsing, the tree can be walked, thus
   retrieving the values.  The code can also be used to build a tree via API then
   write out the tree to a buffer, thus "serializing" the xml.

   It turns out this is useful for other purposes, such as parsing config files.
   YMMV.

   Some Features:
     - output option for xml escaping data.  Choices include no escaping, entity escaping,
       or CDATA sections.
     - output option for character encoding.  Defaults to (none) utf-8.
     - output option for verbosity/readability.  ultra-compact, newlines, pretty/level indented. 

BUGS
   there must be some.

xml_element/xml_elem_free

NAME
   xml_elem_free
SYNOPSIS
   void xml_elem_free(xml_element* root)
FUNCTION
   free an xml element and all of its child elements
INPUTS
   root - the root of an xml tree you would like to free
RESULT
   void
NOTES
SEE ALSO
   xml_elem_free_non_recurse ()
   xml_elem_new ()
SOURCE
    void xml_elem_free(xml_element* root) {
       if(root) {
          xml_element* kids = Q_Head(&root->children);
          while(kids) {
             xml_elem_free(kids);
             kids = Q_Next(&root->children);
          }
          xml_elem_free_non_recurse(root);
       }
    }

xml_element/xml_elem_free_non_recurse

NAME
   xml_elem_free_non_recurse
SYNOPSIS
   void xml_elem_free_non_recurse(xml_element* root)
FUNCTION
   free a single xml element.  child elements will not be freed.
INPUTS
   root - the element to free
RESULT
   void
NOTES
SEE ALSO
   xml_elem_free ()
   xml_elem_new ()
SOURCE
    void xml_elem_free_non_recurse(xml_element* root) {
       if(root) {
          xml_element_attr* attrs = Q_Head(&root->attrs);
          while(attrs) {
             my_free(attrs->key);
             my_free(attrs->val);
             my_free(attrs);
             attrs = Q_Next(&root->attrs);
          }
    
          Q_Destroy(&root->children);
          Q_Destroy(&root->attrs);
          my_free((char*)root->name);
          simplestring_free(&root->text);
          my_free(root);
       }
    }

xml_element/xml_elem_new

NAME
   xml_elem_new
SYNOPSIS
   xml_element* xml_elem_new()
FUNCTION
   allocates and initializes a new xml_element
INPUTS
   none
RESULT
   xml_element* or NULL.  NULL indicates an out-of-memory condition.
NOTES
SEE ALSO
   xml_elem_free ()
   xml_elem_free_non_recurse ()
SOURCE
    xml_element* xml_elem_new() {
       xml_element* elem = calloc(1, sizeof(xml_element));
       if(elem) {
          Q_Init(&elem->children);
          Q_Init(&elem->attrs);
          simplestring_init(&elem->text);
    
          /* init empty string in case we don't find any char data */
          simplestring_addn(&elem->text, "", 0);
       }
       return elem;
    }

xml_element/xml_elem_parse_buf

NAME
   xml_elem_parse_buf
SYNOPSIS
   xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error)
FUNCTION
   parse a buffer containing XML into an xml_element in-memory tree
INPUTS
   in_buf   - buffer containing XML document
   len      - length of buffer
   options  - input options. optional
   error    - error result data. optional. check if result is null.
RESULT
   void
NOTES
   The returned data must be free'd by caller
SEE ALSO
   xml_elem_serialize_to_string ()
   xml_elem_free ()
SOURCE
    xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error)
    {
       xml_element* xReturn = NULL;
       char buf[100] = "";
       static STRUCT_XML_ELEM_INPUT_OPTIONS default_opts = {encoding_utf_8};
    
       if(!options) {
          options = &default_opts;
       }
    
       if(in_buf) {
          XML_Parser parser;
          xml_elem_data mydata = {0};
    
          parser = XML_ParserCreate(NULL);
    
          mydata.root = xml_elem_new();
          mydata.current = mydata.root;
          mydata.input_options = options;
          mydata.needs_enc_conversion = options->encoding && strcmp(options->encoding, encoding_utf_8);
    
          XML_SetElementHandler(parser, startElement, endElement);
          XML_SetCharacterDataHandler(parser, charHandler);
    
          /* pass the xml_elem_data struct along */
          XML_SetUserData(parser, (void*)&mydata);
    
          if(!len) {
             len = strlen(in_buf);
          }
    
          /* parse the XML */
          if(XML_Parse(parser, in_buf, len, 1) == 0) {
             enum XML_Error err_code = XML_GetErrorCode(parser);
             int line_num = XML_GetCurrentLineNumber(parser);
             int col_num = XML_GetCurrentColumnNumber(parser);
             long byte_idx = XML_GetCurrentByteIndex(parser);
             int byte_total = XML_GetCurrentByteCount(parser);
             const XML_LChar XMLPARSEAPI * error_str = XML_ErrorString(err_code);
             if(byte_idx >= 0) {
                 snprintf(buf, 
                          sizeof(buf),
                          "\n\tdata beginning %i before byte index: %s\n",
                          byte_idx > 10  ? 10 : byte_idx,
                          in_buf + (byte_idx > 10 ? byte_idx - 10 : byte_idx));
             }
    
             fprintf(stderr, "expat reports error code %i\n"
                    "\tdescription: %s\n"
                    "\tline: %i\n"
                    "\tcolumn: %i\n"
                    "\tbyte index: %i\n"
                    "\ttotal bytes: %i\n%s ",
                    err_code, error_str, line_num, 
                    col_num, byte_idx, byte_total, buf);
    
    
              /* error condition */
              if(error) {
                  error->parser_code = (long)err_code;
                  error->line = line_num;
                  error->column = col_num;
                  error->byte_index = byte_idx;
                  error->parser_error = error_str;
              }
          }
          else {
             xReturn = (xml_element*)Q_Head(&mydata.root->children);
          }
    
          XML_ParserFree(parser);
    
    
          xml_elem_free_non_recurse(mydata.root);
       }
    
       return xReturn;
    }    

xml_element/xml_elem_serialize_to_stream

NAME
   xml_elem_serialize_to_stream
SYNOPSIS
   void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options)
FUNCTION
   writes element tree as XML into a stream (typically an opened file)
INPUTS
   el      - root element of tree
   output  - stream handle
   options - options determining how output is written.  see XML_ELEM_OUTPUT_OPTIONS
RESULT
   void
NOTES
SEE ALSO
   xml_elem_serialize_to_string ()
   xml_elem_parse_buf ()
SOURCE
    void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options)
    {
       xml_element_serialize(el, file_out_fptr, (void *)output, options, 0);
    }

xml_element/xml_elem_serialize_to_string

NAME
   xml_elem_serialize_to_string
SYNOPSIS
   void xml_element_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len)
FUNCTION
   writes element tree as XML into a newly allocated buffer
INPUTS
   el      - root element of tree
   options - options determining how output is written.  see XML_ELEM_OUTPUT_OPTIONS
   buf_len - length of returned buffer, if not null.
RESULT
   char* or NULL. Must be free'd by caller.
NOTES
SEE ALSO
   xml_elem_serialize_to_stream ()
   xml_elem_parse_buf ()
SOURCE
    char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len)
    {
       simplestring buf;
       simplestring_init(&buf);
    
       xml_element_serialize(el, simplestring_out_fptr, (void *)&buf, options, 0);
    
       if(buf_len) {
          *buf_len = buf.len;
       }
    
       return buf.str;
    }