📄 xml.c
字号:
/* $Id: xml.c,v 1.37 2005/02/20 14:34:16 andrew Exp $ *//* * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <sys/param.h>#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <time.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <clplumbing/ipc.h>#include <clplumbing/cl_log.h> #include <crm/crm.h>#include <crm/msg_xml.h>#include <crm/common/xml.h>#include <crm/dmalloc_wrapper.h>void dump_array( int log_level, const char *message, const char **array, int depth);int print_spaces(char *buffer, int spaces);int log_data_element( const char *function, int log_level, int depth, crm_data_t *data, gboolean formatted);int dump_data_element( int depth, char **buffer, crm_data_t *data, gboolean formatted);#ifndef USE_LIBXMLcrm_data_t *parse_xml(const char *input, int *offset);int get_tag_name(const char *input);int get_attr_name(const char *input);int get_attr_value(const char *input);#endifcrm_data_t *find_xml_node(crm_data_t *root, const char * search_path, gboolean must_find){ if(must_find || root != NULL) { crm_validate_data(root); } if(search_path == NULL) { crm_warn("Will never find <NULL>"); return NULL; } xml_child_iter( root, a_child, search_path,/* crm_insane("returning node (%s).", xmlGetNodePath(a_child)); */ crm_xml_insane(a_child, "contents\t%s"); crm_xml_insane(root, "found in\t%s"); crm_validate_data(a_child); return a_child; ); if(must_find) { crm_warn("Could not find %s in %s.", search_path, xmlGetNodePath(root)); } else if(root != NULL) { crm_devel("Could not find %s in %s.", search_path, xmlGetNodePath(root)); } else { crm_devel("Could not find %s in <NULL>.", search_path); } return NULL;}crm_data_t*find_xml_node_nested(crm_data_t *root, const char **search_path, int len){ int j; gboolean is_found = TRUE; crm_data_t *match = NULL; crm_data_t *lastMatch = root; crm_validate_data(root); if(search_path == NULL || search_path[0] == NULL) { crm_warn("Will never find NULL"); return NULL; } dump_array(LOG_INSANE, "Looking for.", search_path, len); for (j=0; j < len; ++j) { if (search_path[j] == NULL) {/* a NULL also means stop searching */ break; } match = find_xml_node(lastMatch, search_path[j], FALSE); if(match == NULL) { is_found = FALSE; break; } else { lastMatch = match; } } if (is_found) { crm_insane("returning node (%s).", xmlGetNodePath(lastMatch)); crm_xml_insane(lastMatch, "found\t%s"); crm_xml_insane(root, "in \t%s"); crm_validate_data(lastMatch); return lastMatch; } dump_array(LOG_WARNING, "Could not find the full path to the node you specified.", search_path, len); crm_warn("Closest point was node (%s) starting from %s.", xmlGetNodePath(lastMatch), crm_element_name(root)); return NULL; }const char *get_xml_attr_nested(crm_data_t *parent, const char **node_path, int length, const char *attr_name, gboolean error){ const char *attr_value = NULL; crm_data_t *attr_parent = NULL; if(error || parent != NULL) { crm_validate_data(parent); } if(parent == NULL) { crm_devel("Can not find attribute %s in NULL parent",attr_name); return NULL; } if(attr_name == NULL || strlen(attr_name) == 0) { crm_err("Can not find attribute with no name in %s", xmlGetNodePath(parent)); return NULL; } if(length == 0) { attr_parent = parent; } else { attr_parent = find_xml_node_nested(parent, node_path, length); if(attr_parent == NULL && error) { crm_err("No node at the path you specified."); return NULL; } } attr_value = crm_element_value(attr_parent, attr_name); if((attr_value == NULL || strlen(attr_value) == 0) && error) { crm_err( "No value present for %s at %s", attr_name, xmlGetNodePath(attr_parent)); return NULL; } return attr_value;}crm_data_t*find_entity(crm_data_t *parent, const char *node_name, const char *id, gboolean siblings){ crm_validate_data(parent); xml_child_iter( parent, a_child, node_name, if(id == NULL || safe_str_eq(id,crm_element_value(a_child,XML_ATTR_ID))){ crm_devel("returning node (%s).", xmlGetNodePath(a_child)); return a_child; } ); if(siblings) { abort(); } crm_warn("node <%s id=%s> not found in %s.", node_name, id, xmlGetNodePath(parent)); return NULL;}voidcopy_in_properties(crm_data_t* target, crm_data_t *src){ crm_validate_data(src); crm_validate_data(target); if(src == NULL) { crm_warn("No node to copy properties from"); } else if (target == NULL) { crm_err("No node to copy properties into"); } else { xml_prop_iter( src, local_prop_name, local_prop_value, set_xml_property_copy( target, local_prop_name, local_prop_value); ); crm_validate_data(target); } return;}crm_data_t*add_node_copy(crm_data_t *new_parent, crm_data_t *xml_node){ crm_data_t *node_copy = NULL; crm_validate_data(new_parent); crm_validate_data(xml_node); if(xml_node != NULL && new_parent != NULL) {#ifdef USE_LIBXML node_copy = copy_xml_node_recursive(xml_node); xmlAddChild(new_parent, node_copy);#else const char *name = crm_element_name(xml_node); CRM_DEV_ASSERT(HA_OK == ha_msg_addstruct( new_parent, name, xml_node)); node_copy = find_entity(new_parent, crm_element_name(xml_node), ID(xml_node), FALSE); crm_validate_data(node_copy); crm_update_parents(new_parent); crm_validate_data(new_parent);#endif } else if(xml_node == NULL) { crm_err("Could not add copy of NULL node"); } else { crm_err("Could not add copy of node to NULL parent"); } crm_validate_data(node_copy); return node_copy;}const char *set_xml_property_copy(crm_data_t* node, const char *name, const char *value){ const char *parent_name = NULL; if(node != NULL) { parent_name = crm_element_name(node); } crm_insane("[%s] Setting %s to %s", crm_str(parent_name), name, value); if (name == NULL || strlen(name) <= 0) { } else if(node == NULL) { } else if(parent_name == NULL && strcmp(name, F_XML_TAGNAME) != 0) { } else if (value == NULL || strlen(value) <= 0) { xml_remove_prop(node, name); return NULL; } else {#ifdef USE_LIBXML const char *local_name = NULL; const char *local_value = NULL; local_value = crm_strdup(value); local_name = crm_strdup(name); xmlUnsetProp(node, local_name); xmlSetProp(node, local_name, local_value); return xmlGetProp(node, local_name);#else crm_validate_data(node); ha_msg_mod(node, name, value); return crm_element_value(node, name);#endif } return NULL;}crm_data_t*create_xml_node(crm_data_t *parent, const char *name){ const char *local_name = NULL; const char *parent_name = NULL; crm_data_t *ret_value = NULL; if (name == NULL || strlen(name) < 1) { ret_value = NULL; } else {#ifdef USE_LIBXML local_name = crm_strdup(name); if(parent == NULL) ret_value = xmlNewNode(NULL, local_name); else { parent_name = parent->name; ret_value = xmlNewChild(parent, NULL, local_name, NULL); }#else local_name = name; ret_value = ha_msg_new(1); CRM_DEV_ASSERT(ret_value != NULL); set_xml_property_copy(ret_value, XML_ATTR_TAGNAME, name); crm_validate_data(ret_value); if(parent) { crm_validate_data(parent); parent_name = crm_element_name(parent); crm_insane("Attaching %s to parent %s", local_name, parent_name); CRM_DEV_ASSERT(HA_OK == ha_msg_addstruct( parent, name, ret_value)); crm_msg_del(ret_value); crm_update_parents(parent); crm_validate_data(parent); ret_value = parent->values[parent->nfields-1]; crm_validate_data(ret_value); }#endif } crm_insane("Created node [%s [%s]]", crm_str(parent_name), crm_str(local_name));/* set_node_tstamp(ret_value); */ return ret_value;}voidfree_xml_from_parent(crm_data_t *parent, crm_data_t *a_node){ CRM_DEV_ASSERT(parent != NULL); if(parent == NULL) { return; } else if(a_node == NULL) { return; } crm_validate_data(parent);#ifdef USE_LIBXML xmlUnlinkNode(a_node); node->doc = NULL; free_xml_fn(a_node);#else cl_msg_remove_value(parent, a_node); #endif crm_validate_data(parent);}voidfree_xml_fn(crm_data_t *a_node){ if(a_node == NULL) { ; /* nothing to do */#ifdef USE_LIBXML } else if (a_node->doc != NULL) { xmlFreeDoc(a_node->doc); } else { /* make sure the node is unlinked first */ xmlUnlinkNode(a_node); xmlFreeNode(a_node);#else } else { int has_parent = 0; crm_validate_data(a_node); ha_msg_value_int(a_node, XML_ATTR_PARENT, &has_parent); /* there is no way in hell we should be deleting anything * with a parent and without the parent knowning */ CRM_DEV_ASSERT(has_parent == 0); if(has_parent == 0) { crm_validate_data(a_node); crm_msg_del(a_node); }#endif } return;}voidset_node_tstamp(crm_data_t *a_node){ char *since_epoch = NULL; time_t a_time = time(NULL); crm_validate_data(a_node); if(a_time == (time_t)-1) { cl_perror("set_node_tstamp(): Invalid time returned"); return; } crm_malloc(since_epoch, 128*(sizeof(char))); if(since_epoch != NULL) { sprintf(since_epoch, "%ld", (unsigned long)a_time);#ifdef USE_LIBXML xmlUnsetProp(a_node, XML_ATTR_TSTAMP); xmlSetProp(a_node, XML_ATTR_TSTAMP, since_epoch);#else ha_msg_mod(a_node, XML_ATTR_TSTAMP, since_epoch); crm_validate_data(a_node); crm_free(since_epoch);#endif }}crm_data_t*copy_xml_node_recursive(crm_data_t *src_node){ crm_data_t *new_xml = NULL; #ifdef USE_LIBXML# if 1 return xmlCopyNode(src_node, 1);# else xmlNodePtr local_node = NULL, local_child = NULL; if(src_node == NULL || src_node->name == NULL) { return NULL; } local_node = create_xml_node(NULL, src_node->name); copy_in_properties(local_node, src_node); xml_child_iter( src_node, node_iter, NULL, local_child = copy_xml_node_recursive(node_iter); if(local_child != NULL) { xmlAddChild(local_node, local_child); crm_insane("Copied node [%s [%s]", local_node->name, local_child->name); } ); crm_insane("Returning [%s]", local_node->name); return local_node;# endif #else CRM_DEV_ASSERT(src_node != NULL); CRM_DEV_ASSERT(crm_element_name(src_node) != NULL); if(src_node == NULL) { crm_warn("Attempt to dup NULL XML"); return NULL; } else if(crm_element_name(src_node) == NULL) { crm_xml_err(src_node, "Attempt to dup XML with no name"); return NULL; } new_xml = ha_msg_copy(src_node); crm_set_element_parent(new_xml, NULL); crm_update_parents(new_xml); crm_validate_data(new_xml);#endif return new_xml;}crm_data_t*string2xml(const char *input){#ifdef USE_LIBXML int lpc = 0; char ch = 0; int input_len = 0; gboolean more = TRUE; gboolean inTag = FALSE; crm_data_t *xml_object = NULL; const char *the_xml; xmlDocPtr doc; xmlBufferPtr xml_buffer = NULL; if(input == NULL || (input_len = strlen(input)) < 0) { return NULL; } xml_buffer = xmlBufferCreate(); for(lpc = 0; (lpc < input_len) && more; lpc++) { ch = input[lpc]; switch(ch) { case EOF: case 0: ch = 0; more = FALSE; xmlBufferAdd(xml_buffer, &ch, 1); break; case '>':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -