⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml_element.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 2 页
字号:
   }   if(!options) {      options = &default_opts;   }   /* print xml declaration if at root level */   if(depth == 1) {      xml_elem_writefunc(fptr, XML_DECL_START, data, XML_DECL_START_LEN);      xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN);      xml_elem_writefunc(fptr, XML_DECL_VERSION, data, XML_DECL_VERSION_LEN);      if(options->encoding && *options->encoding) {          xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN);          xml_elem_writefunc(fptr, XML_DECL_ENCODING_ATTR, data, XML_DECL_ENCODING_ATTR_LEN);          xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN);          xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);          xml_elem_writefunc(fptr, options->encoding, data, 0);          xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);      }      xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN);      if(options->verbosity != xml_elem_no_white_space) {         xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN);      }   }   if(options->verbosity == xml_elem_pretty && depth > 2) {         xml_elem_writefunc(fptr, whitespace, data, depth - 2);   }   /* begin element */   xml_elem_writefunc(fptr,START_TOKEN_BEGIN, data, START_TOKEN_BEGIN_LEN);   if(el->name) {      xml_elem_writefunc(fptr, el->name, data, 0);      /* write attrs, if any */      if(Q_Size(&el->attrs)) {         xml_element_attr* iter = Q_Head(&el->attrs);         while( iter ) {            xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN);            xml_elem_writefunc(fptr, iter->key, data, 0);            xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN);            xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);            xml_elem_writefunc(fptr, iter->val, data, 0);            xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);            iter = Q_Next(&el->attrs);         }      }   }   else {      xml_elem_writefunc(fptr, "None", data, 0);   }   /* if no text and no children, use abbreviated form, eg: <foo/> */   if(!el->text.len && !Q_Size(&el->children)) {       xml_elem_writefunc(fptr, EMPTY_START_TOKEN_END, data, EMPTY_START_TOKEN_END_LEN);   }   /* otherwise, print element contents */   else {       xml_elem_writefunc(fptr, START_TOKEN_END, data, START_TOKEN_END_LEN);       /* print text, if any */       if(el->text.len) {          char* escaped_str = el->text.str;          int buflen = el->text.len;          if(options->escaping && options->escaping != xml_elem_cdata_escaping) {             escaped_str = xml_elem_entity_escape(el->text.str, buflen, &buflen, options->escaping );             if(!escaped_str) {                escaped_str = el->text.str;             }          }          if(options->escaping & xml_elem_cdata_escaping) {             xml_elem_writefunc(fptr, CDATA_BEGIN, data, CDATA_BEGIN_LEN);          }          xml_elem_writefunc(fptr, escaped_str, data, buflen);          if(escaped_str != el->text.str) {             my_free(escaped_str);          }          if(options->escaping & xml_elem_cdata_escaping) {             xml_elem_writefunc(fptr, CDATA_END, data, CDATA_END_LEN);          }       }       /* no text, so print child elems */       else {          xml_element *kids = Q_Head(&el->children);          i = 0;          while( kids ) {             if(i++ == 0) {                if(options->verbosity != xml_elem_no_white_space) {                   xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN);                }             }             xml_element_serialize(kids, fptr, data, options, depth);             kids = Q_Next(&el->children);          }          if(i) {             if(options->verbosity == xml_elem_pretty && depth > 2) {                   xml_elem_writefunc(fptr, whitespace, data, depth - 2);             }          }       }       xml_elem_writefunc(fptr, END_TOKEN_BEGIN, data, END_TOKEN_BEGIN_LEN);       xml_elem_writefunc(fptr,el->name ? el->name : "None", data, 0);       xml_elem_writefunc(fptr, END_TOKEN_END, data, END_TOKEN_END_LEN);   }   if(options->verbosity != xml_elem_no_white_space) {      xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN);   }}/* print buf to file */static int file_out_fptr(void *f, const char *text, int size){   fputs(text, (FILE *)f);   return 0;}/* print buf to simplestring */static int simplestring_out_fptr(void *f, const char *text, int size){   simplestring* buf = (simplestring*)f;   if(buf) {      simplestring_addn(buf, text, size);   }   return 0;}/****f* 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;}/******//****f* 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);}/******//*--------------------------** End xml_element Functions **--------------------------*//*----------------------* Begin Expat Handlers **---------------------*/typedef struct _xml_elem_data {   xml_element*           root;   xml_element*           current;   XML_ELEM_INPUT_OPTIONS input_options;   int                    needs_enc_conversion;} xml_elem_data;/* expat start of element handler */static void _xmlrpc_startElement(void *userData, const char *name, const char **attrs){   xml_element *c;   xml_elem_data* mydata = (xml_elem_data*)userData;   const char** p = attrs;   if(mydata) {      c = mydata->current;      mydata->current = xml_elem_new();      mydata->current->name = (char*)strdup(name);      mydata->current->parent = c;      /* init attrs */      while(p && *p) {         xml_element_attr* attr = malloc(sizeof(xml_element_attr));         if(attr) {            attr->key = strdup(*p);            attr->val = strdup(*(p+1));            Q_PushTail(&mydata->current->attrs, attr);            p += 2;         }      }   }}/* expat end of element handler */static void _xmlrpc_endElement(void *userData, const char *name){   xml_elem_data* mydata = (xml_elem_data*)userData;   if(mydata && mydata->current && mydata->current->parent) {      Q_PushTail(&mydata->current->parent->children, mydata->current);      mydata->current = mydata->current->parent;   }}/* expat char data handler */static void _xmlrpc_charHandler(void *userData,                        const char *s,                        int len){   xml_elem_data* mydata = (xml_elem_data*)userData;   if(mydata && mydata->current) {      /* Check if we need to decode utf-8 parser output to another encoding */      if(mydata->needs_enc_conversion && mydata->input_options->encoding) {         int new_len = 0;         char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding);         if(add_text) {            len = new_len;            simplestring_addn(&mydata->current->text, add_text, len);            free(add_text);            return;         }      }      simplestring_addn(&mydata->current->text, s, len);   }}/******//*-------------------** End Expat Handlers **-------------------*//*-------------------** xml_elem_parse_buf **-------------------*//****f* 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, (XML_StartElementHandler)_xmlrpc_startElement, (XML_EndElementHandler)_xmlrpc_endElement);      XML_SetCharacterDataHandler(parser, (XML_CharacterDataHandler)_xmlrpc_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 char * error_str = XML_ErrorString(err_code);         if(byte_idx >= 0) {             snprintf(buf,                       sizeof(buf),                      "\n\tdata beginning %ld 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: %ld\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);         xReturn->parent = NULL;      }      XML_ParserFree(parser);      xml_elem_free_non_recurse(mydata.root);   }   return xReturn;}/******/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -