static GNode *xml_build_tree(XMLFile *file, GNode *parent, guint level) { GNode *node = NULL; XMLNode *xmlnode; XMLTag *tag; while (xml_parse_next_tag(file) == 0) { if (file->level < level) break; if (file->level == level) { g_warning("xml_build_tree(): Parse error in %s", file->path); break; } tag = xml_get_current_tag(file); if (!tag) break; xmlnode = xml_node_new(xml_copy_tag(tag), NULL); xmlnode->element = xml_get_element(file); if (!parent) node = g_node_new(xmlnode); else node = g_node_append_data(parent, xmlnode); xml_build_tree(file, node, file->level); if (file->level == 0) break; } return node; }
static void xmlprops_read_props( XmlProperty *props, XMLFile *file ) { GList *attr; gchar *name, *value; gchar *pName; gchar *pValue; while( TRUE ) { pName = g_strdup(""); pValue = g_strdup(""); if (! file->level ) break; xml_parse_next_tag( file ); xml_get_current_tag( file ); if( xml_compare_tag( file, XMLS_ELTAG_PROPERTY ) ) { attr = xml_get_current_tag_attr( file ); while( attr ) { name = ( ( XMLAttr * ) attr->data )->name; value = ( ( XMLAttr * ) attr->data )->value; if( strcmp( name, XMLS_ATTAG_NAME ) == 0 ) { g_free(pName); pName = g_strdup( value ); } else if( strcmp( name, XMLS_ATTAG_VALUE ) == 0 ) { g_free(pValue); pValue = g_strdup( value ); } attr = g_list_next( attr ); } xmlprops_save_property( props, pName, pValue ); } g_free(pName); g_free(pValue); } }
GList *xml_get_current_tag_attr(XMLFile *file) { XMLTag *tag; tag = xml_get_current_tag(file); if (!tag) return NULL; return tag->attr; }
gboolean xml_compare_tag(XMLFile *file, const gchar *name) { XMLTag *tag; tag = xml_get_current_tag(file); if (tag && strcmp(tag->tag, name) == 0) return TRUE; else return FALSE; }
gint xml_parse_next_tag(XMLFile *file) { gchar buf[XMLBUFSIZE]; gchar *bufp = buf; gchar *tag_str; XMLTag *tag; gint len; next: if (file->is_empty_element == TRUE) { file->is_empty_element = FALSE; xml_pop_tag(file); return 0; } if (xml_get_parenthesis(file, buf, sizeof(buf)) < 0) { g_warning("xml_parse_next_tag(): Can't parse next tag in %s", file->path); return -1; } len = strlen(buf); /* end-tag */ if (buf[0] == '/') { if (strcmp(xml_get_current_tag(file)->tag, buf + 1) != 0) { g_warning("xml_parse_next_tag(): Tag name mismatch in %s : %s (%s)", file->path, buf, xml_get_current_tag(file)->tag); return -1; } xml_pop_tag(file); return 0; } if (len >= 7 && !strncmp(buf, "!-- ", 4) && !strncmp(buf+len-3, " --", 3)) { /* skip comment */ goto next; } tag = xml_tag_new(NULL); xml_push_tag(file, tag); if (len > 0 && buf[len - 1] == '/') { file->is_empty_element = TRUE; buf[len - 1] = '\0'; g_strchomp(buf); } if (strlen(buf) == 0) { g_warning("xml_parse_next_tag(): Tag name is empty in %s", file->path); return -1; } while (*bufp != '\0' && !g_ascii_isspace(*bufp)) bufp++; if (*bufp == '\0') { if (file->need_codeconv) { tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL); if (tag_str) { tag->tag = XML_STRING_ADD(tag_str); g_free(tag_str); } else tag->tag = XML_STRING_ADD(buf); } else tag->tag = XML_STRING_ADD(buf); return 0; } else { *bufp++ = '\0'; if (file->need_codeconv) { tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL); if (tag_str) { tag->tag = XML_STRING_ADD(tag_str); g_free(tag_str); } else tag->tag = XML_STRING_ADD(buf); } else tag->tag = XML_STRING_ADD(buf); } /* parse attributes ( name=value ) */ while (*bufp) { XMLAttr *attr; gchar *attr_name; gchar *attr_value; gchar *utf8_attr_name; gchar *utf8_attr_value; gchar *p; gchar quote; while (g_ascii_isspace(*bufp)) bufp++; attr_name = bufp; if ((p = strchr(attr_name, '=')) == NULL) { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (a) %s", file->path, attr_name); return -1; } bufp = p; *bufp++ = '\0'; while (g_ascii_isspace(*bufp)) bufp++; if (*bufp != '"' && *bufp != '\'') { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (b) %s", file->path, bufp); return -1; } quote = *bufp; bufp++; attr_value = bufp; if ((p = strchr(attr_value, quote)) == NULL) { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (c) %s", file->path, attr_value); return -1; } bufp = p; *bufp++ = '\0'; g_strchomp(attr_name); xml_unescape_str(attr_value); if (file->need_codeconv) { utf8_attr_name = conv_codeset_strdup (attr_name, file->encoding, CS_INTERNAL); utf8_attr_value = conv_codeset_strdup (attr_value, file->encoding, CS_INTERNAL); if (!utf8_attr_name) utf8_attr_name = g_strdup(attr_name); if (!utf8_attr_value) utf8_attr_value = g_strdup(attr_value); attr = xml_attr_new(utf8_attr_name, utf8_attr_value); g_free(utf8_attr_value); g_free(utf8_attr_name); } else { attr = xml_attr_new(attr_name, attr_value); } xml_tag_add_attr(tag, attr); } tag->attr = g_list_reverse(tag->attr); return 0; }