/** * nmp_get_node_attr_value: get value of an attribute * * @xml_buf: input, pointer of xml text buffer * @xml_len: input, xml text buffer length * @xpath: input, addressing parts of an XML document * @attribute: input, attribute * @attr_value: output, attribute value * @return: succeed 0, else -1 */ int nmp_get_node_attr_value( const char *xml_buff, int xml_len, xmlChar *xpath, xmlChar *attribute, xmlChar *attr_value ) { ASSERT((xml_buff != NULL) && (xpath!=NULL) && (attribute != NULL) && (attr_value != NULL)); xmlDocPtr doc; char *cmd; xmlXPathObjectPtr app_result; int i; doc = xmlParseMemory(xml_buff, xml_len); //doc = xmlParseDoc(&xml_buff); if (doc == NULL ) { xml_error("Document not parsed successfully. \n"); return -1; } app_result = nmp_get_node(doc, (const xmlChar *)xpath); if (app_result == NULL) goto end; if (app_result) { xmlNodeSetPtr nodeset = app_result->nodesetval; //*value_num = nodeset->nodeNr; xml_debug(" nodeset->nodeNr=%d\n", nodeset->nodeNr); for (i=0; i < nodeset->nodeNr; i++) { cmd = (char *)xmlGetProp(nodeset->nodeTab[i], (const xmlChar *)attribute); xml_debug("cmd type =%s\n",cmd); memcpy(attr_value,cmd,strlen(cmd)); xml_debug("attr_value type =%s\n",attr_value); xmlFree(cmd); } xmlXPathFreeObject(app_result); } end: xmlFreeDoc(doc); return 0; }
/* * Process command. When we get here, we've processed "<!-" */ xml_token_type_t xml_skip_comment(xml_reader_t *xr) { int match = 0, cc; if (xml_getc(xr) != '-') { xml_parse_error(xr, "Unexpected <!-...> element"); return None; } while ((cc = xml_getc(xr)) != EOF) { if (cc == '-') { match++; } else { if (cc == '>' && match >= 2) { #ifdef XMLDEBUG_PARSER xml_debug("Processed comment\n"); #endif return Comment; } match = 0; } } xml_parse_error(xr, "Unexpected end of file while parsing comment"); return None; }
static void handleElement(struct XMLstate *state) { DM_RESULT res; xml_debug("handling data: %s\n", state->text ? : "NOTHING"); res = dm_string2value(state->element, state->text, flags & DS_USERCONFIG, state->value); #ifdef XML_DEBUG if (res != DM_OK) xml_debug("dm_string2value returned %d (DM_RESULT)\n", res); #endif }
/** * nmp_add_new_node: add a new node * * @xml_in: input, pointer of xml text buffer * @len_in: iutput, xml text buffer length * @xml_out: output, pointer of buffer block, containing xml text * after deleting a node * @len_out: output, indicate buffer length of xml_out * @xpath: addressing parts of an XML document * @node_name: node name * @node_cont: node content * @return: succeed 0, else -1 */ int nmp_add_new_node( const char *xml_in, int len_in, xmlChar *xml_out, int *len_out, xmlChar *xpath, xmlChar *node_name, xmlChar *node_cont ) { ASSERT(xml_in != NULL && xml_out!= NULL && xpath != NULL); xmlDocPtr doc; xmlNodePtr node; xmlXPathObjectPtr app_result; int node_num;; xmlChar *xml_buffer; doc = xmlParseMemory(xml_in, len_in); //doc = xmlParseDoc(&xml_buff); if (doc == NULL ) { xml_error("Document not parsed successfully. \n"); return -1; } app_result = nmp_get_node(doc, (const xmlChar *)xpath); if (app_result == NULL) goto end; if (app_result) { xmlNodeSetPtr nodeset = app_result->nodesetval; node_num = nodeset->nodeNr - 1; node = xmlNewNode(NULL, BAD_CAST node_name); xmlNodeSetContent(node, (const xmlChar *)node_cont); xmlAddNextSibling ( nodeset->nodeTab[node_num],node); xmlSaveFormatFileEnc("-", doc, ECODE_UFT8, 1); xmlDocDumpMemoryEnc(doc, &xml_buffer, len_out,ECODE_UFT8); xml_debug("xml_buffer=%s\n", xml_buffer); memcpy(xml_out,xml_buffer,*len_out); xmlFree(xml_buffer); xmlXPathFreeObject(app_result); } end: xmlFreeDoc(doc); return 0; }
/** * nmp_modify_attr_value: modify attribute's value in XML document * * @xml_in: input, pointer of xml text buffer * @len_in: iutput, xml text buffer length * @xml_out: output, pointer of buffer block, containing xml text * after modifying attribute value * @len_out: output, indicate buffer length of xml_out * @xpath: addressing parts of an XML document * @attribute: XML element attribute * @attr_value: value of a specific attribute in XML document * @return: succeed 0, else -1 */ int nmp_modify_attr_value( const char *xml_in, int len_in, xmlChar *xml_out, int *len_out, xmlChar *xpath, xmlChar *attribute, xmlChar *attr_value ) { ASSERT(xml_out != NULL && attribute!=NULL && attr_value!= NULL); xmlDocPtr doc; xmlXPathObjectPtr app_result; int node_num;; xmlChar *xml_buffer; doc = xmlParseMemory(xml_in, len_in); //doc = xmlParseDoc(&xml_buff); if (doc == NULL ) { xml_error("Document not parsed successfully. \n"); return -1; } app_result = nmp_get_node(doc, (const xmlChar *)xpath); if (app_result == NULL) { goto end; } if (app_result) { xmlNodeSetPtr nodeset = app_result->nodesetval; //*value_num = nodeset->nodeNr; xml_debug(" nodeset->nodeNr=%d\n", nodeset->nodeNr); node_num = nodeset->nodeNr - 1; xmlSetProp(nodeset->nodeTab[0], BAD_CAST attribute, BAD_CAST attr_value); xmlSaveFormatFileEnc("-", doc, ECODE_UFT8, 1); xmlDocDumpMemoryEnc(doc, &xml_buffer, len_out,ECODE_UFT8); memcpy(xml_out, xml_buffer, *len_out); xmlFree(xml_buffer); xmlXPathFreeObject(app_result); } end: xmlFreeDoc(doc); return 0; }
xml_token_type_t xml_get_tag_attributes(xml_reader_t *xr, xml_node_t *node) { ni_stringbuf_t tokenValue, attrName, attrValue; xml_token_type_t token; ni_stringbuf_init(&tokenValue); ni_stringbuf_init(&attrName); ni_stringbuf_init(&attrValue); token = xml_get_token(xr, &tokenValue); while (1) { if (token == RightAngle || token == RightAngleQ || token == RightAngleSlash) break; if (token != Identifier) { xml_parse_error(xr, "Unexpected token in tag attributes"); token = None; break; } ni_stringbuf_move(&attrName, &tokenValue); token = xml_get_token(xr, &tokenValue); if (token != Equals) { xml_node_add_attr(node, attrName.string, NULL); continue; } token = xml_get_token(xr, &tokenValue); if (token != QuotedString) { xml_parse_error(xr, "Attribute value not a quoted string!"); token = None; break; } xml_debug(" attr %s=%s\n", attrName.string, tokenValue.string); xml_node_add_attr(node, attrName.string, tokenValue.string); token = xml_get_token(xr, &tokenValue); } ni_stringbuf_destroy(&tokenValue); ni_stringbuf_destroy(&attrName); ni_stringbuf_destroy(&attrValue); return token; }
ni_bool_t xml_process_element_nested(xml_reader_t *xr, xml_node_t *cur, unsigned int nesting) { ni_stringbuf_t tokenValue, identifier; xml_token_type_t token; xml_node_t *child; ni_stringbuf_init(&tokenValue); ni_stringbuf_init(&identifier); while (1) { token = xml_get_token(xr, &tokenValue); switch (token) { case CData: /* process element content */ xml_node_set_cdata(cur, tokenValue.string); break; case LeftAngleExclam: /* Most likely <!DOCTYPE ...> */ if (!xml_get_identifier(xr, &identifier)) { xml_parse_error(xr, "Bad element: tag open <! not followed by identifier"); goto error; } if (strcmp(identifier.string, "DOCTYPE")) { xml_parse_error(xr, "Unexpected element: <!%s ...> not supported", identifier.string); goto error; } while (1) { token = xml_get_token(xr, &identifier); if (token == RightAngle) break; if (token == Identifier && !xr->doctype) ni_string_dup(&xr->doctype, identifier.string); if (token != Identifier && token != QuotedString) { xml_parse_error(xr, "Error parsing <!DOCTYPE ...> attributes"); goto error; } } break; case LeftAngle: /* New element start */ if (!xml_get_identifier(xr, &identifier)) { xml_parse_error(xr, "Bad element: tag open < not followed by identifier"); goto error; } child = xml_node_new(identifier.string, cur); if (xr->shared_location) child->location = xml_location_new(xr->shared_location, xr->lineCount); token = xml_get_tag_attributes(xr, child); if (token == None) { xml_parse_error(xr, "Error parsing <%s ...> tag attributes", child->name); goto error; } else if (token == RightAngle) { /* Handle <foo>...</foo> */ xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name); if (!xml_process_element_nested(xr, child, nesting + 2)) goto error; } else if (token == RightAngleSlash) { /* We parsed a "<foo/>" element - nothing left to do, we're done */ xml_debug("%*.*s<%s/>\n", nesting, nesting, "", child->name); } else { xml_parse_error(xr, "Unexpected token %s at end of <%s ...", xml_token_name(token), child->name); goto error; } break; case LeftAngleSlash: /* Element end */ if (!xml_get_identifier(xr, &identifier)) { xml_parse_error(xr, "Bad element: end tag open </ not followed by identifier"); goto error; } if (xml_get_token(xr, &tokenValue) != RightAngle) { xml_parse_error(xr, "Bad element: </%s - missing tag close", identifier.string); goto error; } if (cur->parent == NULL) { xml_parse_error(xr, "Unexpected </%s> tag", identifier.string); goto error; } if (strcmp(cur->name, identifier.string)) { xml_parse_error(xr, "Closing tag </%s> does not match <%s>", identifier.string, cur->name); goto error; } xml_debug("%*.*s</%s>\n", nesting, nesting, "", cur->name); goto success; case LeftAngleQ: /* New PI node starts here */ if (!xml_get_identifier(xr, &identifier)) { xml_parse_error(xr, "Bad element: tag open <? not followed by identifier"); goto error; } child = xml_node_new(identifier.string, NULL); if (xr->shared_location) child->location = xml_location_new(xr->shared_location, xr->lineCount); token = xml_get_tag_attributes(xr, child); if (token == None) { xml_parse_error(xr, "Error parsing <?%s ...?> tag attributes", child->name); xml_node_free(child); goto error; } else if (token == RightAngleQ) { xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name); xml_process_pi_node(xr, child); xml_node_free(child); } else { xml_parse_error(xr, "Unexpected token %s at end of <?%s ...", xml_token_name(token), child->name); xml_node_free(child); goto error; } break; case EndOfDocument: if (cur->parent) { xml_parse_error(xr, "End of document while processing element <%s>", cur->name); goto error; } goto success; case None: /* parser error */ goto error; default: xml_parse_error(xr, "Unexpected token %s", xml_token_name(token)); goto error; } } success: ni_stringbuf_destroy(&tokenValue); ni_stringbuf_destroy(&identifier); return TRUE; error: ni_stringbuf_destroy(&tokenValue); ni_stringbuf_destroy(&identifier); return FALSE; }
static void XMLCALL startElement(void *userData, const char *name, const char **atts) { const struct dm_element *kw = NULL; DM_VALUE *val = NULL; struct XMLstate **state = userData; const char *base = (*state)->base; int valid = ((*state)->flags & XML_VALID) == XML_VALID; int is_root = ((*state)->flags & XML_ROOT) == XML_ROOT; const struct dm_element *element = (*state)->element; DM_VALUE *value = (*state)->value; int xid = 0; int ntfy = 0; dm_id id; for (int i = 0; atts[i]; i += 2) { if (strcasecmp("instance", atts[i]) == 0) { xml_debug("%s: instance: %s\n", name, atts[i + 1]); xid = atoi(atts[i + 1]); break; } else if (strcasecmp("notify", atts[i]) == 0) { xml_debug("%s: notify: %s\n", name, atts[i + 1]); ntfy = dm_enum2int( ¬ify_attr, atts[i + 1]); } else if (strcasecmp("encoding", atts[i]) == 0) { xml_debug("%s: encoding: %s\n", name, atts[i + 1]); if (strcasecmp(atts[i+1], "escaped") == 0) (*state)->flags |= XML_ESCAPED; } else if (strcasecmp("version", atts[i]) == 0) { xml_debug("%s: config version: %s\n", name, atts[i + 1]); dm_set_cfg_version(atoi(atts[i + 1])); } } (*state)++; if (is_root) { if (flags & DS_VERSIONCHECK && dm_get_cfg_version() != CFG_VERSION) { (*state)->flags |= XML_UPGRADE; lua_pushinteger(lua_environment, CFG_VERSION); lua_pushinteger(lua_environment, dm_get_cfg_version()); if (fp_Lua_function("fncPreVersionCheck", 2)) debug("(): Error during Lua function execution"); } } else { memset(*state, 0, sizeof(struct XMLstate)); if (xid != 0) asprintf(&(*state)->base, "%s.%s.%d", base, name, xid); else asprintf(&(*state)->base, "%s.%s", base, name); if (valid) { const struct dm_table *table = element->u.t.table; id = dm_get_element_id_by_name(name, strlen(name), table); if (id != DM_ERR) { kw = &(table->table[id - 1]); val = dm_get_value_ref_by_id(DM_TABLE(*value), id); (*state)->flags |= XML_VALID; } else { printf("Element '%s' not found in table '%s'\n", name, element->key); valid = 0; } } if (!valid || !((*state)->flags & XML_VALID)) { debug("enter invalid: %s\n", (*state)->base); return; } xml_debug("enter: %s = %p, (%p, %p)\n", name, *state, kw, val); (*state)->element = kw; if (kw->type == T_OBJECT) { struct dm_instance *inst = DM_INSTANCE(*val); struct dm_instance_node *node = NULL; /** FIXME: this should be easier */ if (xid > 0) node = dm_get_instance_node_by_id(inst, xid); if (!node) { dm_selector basesel; dm_selcpy(basesel, DM_TABLE(*value)->id); dm_selcat(basesel, id); node = dm_add_instance(kw, inst, basesel, xid); dm_assert(node); if (flags & DS_USERCONFIG) { val->flags |= DV_UPDATED; DM_parity_update(*val); node->table.flags |= DV_UPDATED; DM_parity_update(node->table); } } val = &node->table; (*state)->inst = inst; (*state)->node = node; } else if (kw->type == T_TOKEN) { if (DM_TABLE(*val) == NULL) { set_DM_TABLE(*val, dm_alloc_table(kw->u.t.table, DM_TABLE(*value)->id, id)); if (flags & DS_USERCONFIG) val->flags |= DV_UPDATED; xml_debug("adding table for token \"%s\" with %d elements: %p\n", name, kw->u.t.table->size, DM_TABLE(*val)); DM_parity_update(*val); } } (*state)->value = val; if (ntfy >= 0) set_notify_single_slot_element(kw, (*state)->value, 0, ntfy); } }