00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: xmlwrite.c,v 1.11 2004-09-26 09:42:09 stdarg Exp $";
00022 #endif
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <stdarg.h>
00028
00029 #include <eggdrop/eggdrop.h>
00030
00031 #define XML_INDENT_CHAR '\t'
00032
00033 static int write_options = XML_NONE;
00034
00035 static int xml_write_node(FILE *fp, xml_node_t *node);
00036
00037 static int level = 0;
00038 static char indent[32] = {0};
00039
00040 static int xml_write_children(FILE *fp, xml_node_t *node)
00041 {
00042 int ret = 0;
00043 const char *text;
00044
00045
00046 memset(indent, '\t', sizeof(indent));
00047
00048 indent[++level] = 0;
00049
00050
00051 text = node->text;
00052 if (text && *text) fprintf(fp, "%s%s\n", indent, text);
00053
00054 for (node = node->children; node; node = node->next) {
00055 fprintf(fp, "%s", indent);
00056 if ((ret = xml_write_node(fp, node)) == -1) break;
00057 }
00058
00059 indent[--level] = 0;
00060
00061 return ret;
00062 }
00063
00064 static int xml_write_attributes(FILE *fp, xml_node_t *node)
00065 {
00066 int i;
00067 xml_attr_t *attr;
00068
00069 for (i = 0; i < node->nattributes; i++) {
00070 attr = node->attributes[i];
00071 if (attr->value) fprintf(fp, " %s=\"%s\"", attr->name, attr->value);
00072 }
00073
00074 return (0);
00075 }
00076
00077 static int xml_write_element(FILE *fp, xml_node_t *node)
00078 {
00079 fprintf(fp, "<%s", node->name);
00080
00081 if (xml_write_attributes(fp, node) == -1) return(-1);
00082
00083 if (node->nchildren == 0) {
00084 if (node->text) {
00085 fprintf(fp, ">%s</%s>\n", node->text, node->name);
00086 } else {
00087 fprintf(fp, "/>\n");
00088 }
00089
00090 return (0);
00091 }
00092
00093 fprintf(fp, ">\n");
00094 if (xml_write_children(fp, node) != 0) return(-1);
00095
00096 fprintf(fp, "%s</%s>\n", indent, node->name);
00097 return(0);
00098 }
00099
00100 static int xml_write_document(FILE *fp, xml_node_t *node)
00101 {
00102 int ret;
00103
00104 ret = 0;
00105 for (node = node->children; node; node = node->next) {
00106 if ((ret = xml_write_node(fp, node)) != 0)
00107 break;
00108 }
00109 return ret;
00110 }
00111
00112 static int xml_write_comment(FILE *fp, xml_node_t *node)
00113 {
00114
00115 fprintf(fp, "<!--%s-->\n", node->text);
00116 return(0);
00117 }
00118
00119 static int xml_write_cdata_section(FILE *fp, xml_node_t *node)
00120 {
00121 fprintf(fp, "<![CDATA[%s]]>\n", node->text);
00122 return(0);
00123 }
00124
00125 static int xml_write_processing_instruction(FILE *fp, xml_node_t *node)
00126 {
00127 fprintf(fp, "<?%s", node->name);
00128
00129 if (xml_write_attributes(fp, node) != 0) return(-1);
00130
00131 fprintf(fp, "?>\n");
00132
00133 return (0);
00134 }
00135
00136 static int xml_write_node(FILE *fp, xml_node_t *node)
00137 {
00138 switch (node->type) {
00139
00140 case (XML_DOCUMENT):
00141 return xml_write_document(fp, node);
00142
00143 case (XML_ELEMENT):
00144 return xml_write_element(fp, node);
00145
00146 case (XML_COMMENT):
00147 return xml_write_comment(fp, node);
00148
00149 case (XML_CDATA_SECTION):
00150 return xml_write_cdata_section(fp, node);
00151
00152 case (XML_PROCESSING_INSTRUCTION):
00153 return xml_write_processing_instruction(fp, node);
00154
00155 case (XML_ATTRIBUTE):
00156
00157 return (0);
00158 }
00159
00160 xml_set_error("unknown node type");
00161
00162 return (-1);
00163 }
00164
00165 int xml_save_file(const char *file, xml_node_t *node, int options)
00166 {
00167 FILE *fp;
00168 int ret;
00169
00170
00171 xml_set_error(NULL);
00172
00173 fp = fopen(file, "w");
00174
00175 if (!fp) {
00176 xml_set_error("failed to open file");
00177 return -1;
00178 }
00179
00180 write_options = options;
00181 ret = xml_write_node(fp, node);
00182 write_options = XML_NONE;
00183
00184 fclose(fp);
00185
00186 return ret;
00187 }