/home/dko/projects/mobilec/trunk/src/xml_helper.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */
00004 /*[
00005  * Copyright (c) 2007 Integration Engineering Laboratory
00006  University of California, Davis
00007  *
00008  * Permission to use, copy, and distribute this software and its
00009  * documentation for any purpose with or without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.
00013  *
00014  * Permission to modify the software is granted, but not the right to
00015  * distribute the complete modified source code. Modifications are to
00016  * be distributed as patches to the released version. Permission to
00017  * distribute binaries produced by compiling modified sources is granted,
00018  * provided you
00019  * 1. distribute the corresponding source modifications from the
00020  * released version in the form of a patch file along with the binaries,
00021  * 2. add special version identification to distinguish your version
00022  * in addition to the base release version number,
00023  * 3. provide your name and address as the primary contact for the
00024  * support of your modified version, and
00025  * 4. retain our contact information in regard to use of the base
00026  * software.
00027  * Permission to distribute the released version of the source code along
00028  * with corresponding source modifications in the form of a patch file is
00029  * granted with same provisions 2 through 4 for binary distributions.
00030  *
00031  * This software is provided "as is" without express or implied warranty
00032  * to the extent permitted by applicable law.
00033 ]*/
00034 
00035 /* These are xml helper functions.
00036  *
00037  * They were created to ease the switch from libxml2 to mxml.
00038  *
00039  * Written by David Ko <dko@ucdavis.edu> 2006 */
00040 
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 #include <mxml.h>
00045 #include "include/xml_helper.h"
00046 #include "include/macros.h"
00047 
00048 mxml_node_t *
00049 xml_find_sibling(const mxml_node_t *node, const char *sibling_name)
00050 {
00051 if ( !strcmp(
00052 xml_get_element_name(node),
00053 sibling_name
00054 )
00055 ) {
00056 return (mxml_node_t *)node;
00057 } else {
00058 return mxmlFindElement( (mxml_node_t *)node,
00059 (mxml_node_t *)node->parent,
00060 sibling_name,
00061 NULL,
00062 NULL,
00063 MXML_NO_DESCEND );
00064 }
00065 }
00066 
00067 /* xml_get_cdata 
00068  * Expects an MXML_ELEMENT with CDATA (returns the data) or a 
00069  * MXML_TEXT node (returns the text). */
00070 char * 
00071 xml_get_cdata(const mxml_node_t *node) {
00072 char *cdata_str;
00073 char *tmp;
00074 const char *buf;
00075 if (node == NULL) {
00076 return NULL;
00077 } else if ( node->type != MXML_ELEMENT) {
00078 return NULL;
00079 }
00080 /* The name of the node should begin with '![CDATA[' and end with ']]' */
00081 buf = xml_get_element_name(node);
00082 cdata_str = (char *)malloc(sizeof(char) * (strlen(buf) + 1));
00083 tmp = strstr(buf, "![CDATA[");
00084 if (tmp == NULL) {
00085 return NULL;
00086 }
00087 tmp = tmp + strlen("![CDATA["); /* Now tmp points to the beginning of the string. */
00088 strcpy(cdata_str, tmp);
00089 for (tmp = cdata_str; *(tmp+2) != '0円'; tmp++) {
00090 if (*tmp == '0円') {
00091 return NULL;
00092 }
00093 }
00094 /* Last two characters must be ']]' */
00095 if ( strcmp(tmp, "]]") ) {
00096 return NULL;
00097 }
00098 CHECK_NULL(tmp, return NULL);
00099 *tmp = '0円';
00100 return cdata_str;
00101 }
00102 
00103 mxml_node_t *
00104 xml_get_child(const mxml_node_t *node, const char *child_name, int descend)
00105 {
00106 return mxmlFindElement( (mxml_node_t *)node,
00107 (mxml_node_t *)node,
00108 child_name,
00109 NULL,
00110 NULL,
00111 descend );
00112 }
00113 
00114 /* Function: xml_get_deep_child
00115 Arguments: parent: The parent node
00116 child_path: The relative path to the child from the
00117 parent. It is an array of strings terminated
00118 by NULL.
00119 Return Value: A valid xmlNodePtr to the child on success, NULL
00120 on failure.
00121  */
00122 mxml_node_t *
00123 xml_get_deep_child(const mxml_node_t *parent, const char **child_path)
00124 {
00125 int i;
00126 mxml_node_t *node;
00127 node = (mxml_node_t *)parent;
00128 for (i=0; child_path[i] != NULL; i++) {
00129 if ( (node = xml_get_child(node, child_path[i], MXML_NO_DESCEND)) == NULL) {
00130 return NULL;
00131 }
00132 }
00133 return node;
00134 }
00135 
00136 mxml_node_t *
00137 xml_get_next_element(const mxml_node_t *node)
00138 {
00139 node = node->next;
00140 while (node != NULL) {
00141 if (node->type == MXML_ELEMENT) {
00142 break;
00143 }
00144 node = node->next;
00145 }
00146 return (mxml_node_t *)node;
00147 }
00148 
00149 /* Function: xml_get_text
00150  Given a node, it will malloc and return a character string with 
00151  the text of the node. For instance, for a node that looks like
00152  <node> Hello There <\node>
00153  xml_get_text(node_ptr) will return the string "Hello There". */
00154 
00155 char * xml_get_text(const mxml_node_t *node)
00156 {
00157 char *ret;
00158 char *tmp;
00159 mxml_node_t *it; /* iteration temp node */
00160 int len = 0;
00161 if (node->child) {
00162 node = node->child;
00163 } else {
00164 return NULL;
00165 }
00166 
00167 if (node->type == MXML_TEXT || node->type == MXML_ELEMENT) {
00168 /* First, find total string length. */
00169 it = (mxml_node_t *)node;
00170 while (it != NULL && 
00171 (it->type == MXML_TEXT || it->type == MXML_ELEMENT)
00172 ){
00173 if (it->type == MXML_TEXT) {
00174 len += strlen(it->value.text.string);
00175 len++; /*Account for whitespace*/
00176 it = it->next;
00177 } else if (it->type == MXML_ELEMENT) {
00178 if ((tmp = strstr(it->value.element.name, "![CDATA["))){
00179 len += strlen(tmp);
00180 it = it->next;
00181 } else {
00182 break;
00183 }
00184 } else {
00185 break;
00186 }
00187 }
00188 } else {
00189 return NULL;
00190 }
00191 ret = malloc( sizeof(char) * (len + 1));
00192 *ret = '0円';
00193 for ( 
00194 it = (mxml_node_t *)node; 
00195 it != NULL && (it->type == MXML_TEXT || it->type == MXML_ELEMENT); 
00196 it = it->next) {
00197 if (it->type == MXML_TEXT) {
00198 if (it->value.text.whitespace == 1) {
00199 strcat(ret, " ");
00200 } 
00201 strcat(ret, it->value.text.string);
00202 } else if (it->type == MXML_ELEMENT) {
00203 if ((tmp = xml_get_cdata(it))) {
00204 /* strcat(ret, " "); */
00205 strcat(ret, tmp);
00206 free(tmp);
00207 } else {
00208 break;
00209 }
00210 } else { /* Should never get here */
00211 CHECK_NULL( NULL, exit(0) );
00212 }
00213 }
00214 return ret;
00215 }
00216 
00217 const char* xml_get_element_name(const mxml_node_t *node)
00218 {
00219 if (node->type != MXML_ELEMENT) {
00220 return NULL;
00221 } else {
00222 return node->value.element.name;
00223 }
00224 }
00225 
00226 /* xml_new_cdata
00227  *
00228  * Creates a new cdata node under 'parent'. */
00229 mxml_node_t *
00230 xml_new_cdata(mxml_node_t* parent, const char* text) {
00231 char *tmp;
00232 int namelen;
00233 mxml_node_t * node;
00234 namelen = (strlen(text) + strlen("![CDATA[]]")+1) * sizeof(char);
00235 tmp = (char*)malloc(namelen);
00236 CHECK_NULL(tmp, exit(0) );
00237 *tmp = '0円';
00238 strcat(tmp, "![CDATA[");
00239 strcat(tmp, text);
00240 strcat(tmp, "]]");
00241 node = mxmlNewElement(
00242 parent,
00243 (const char*)tmp );
00244 free((char*)tmp); 
00245 return node;
00246 }
00247 /* This is a simple whitespace callback for mxml */
00248 const char* 
00249 whitespace_cb( mxml_node_t *node, 
00250 int where ) 
00251 {
00252 if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE) {
00253 return("\n");
00254 } else {
00255 return NULL;
00256 }
00257 }

Generated on Tue Oct 28 17:03:23 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /