📄 xmlutils.c
字号:
/* $Id: xmlutils.c,v 1.11.2.2 2004/09/11 06:36:31 msoffen 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 <portability.h>#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <time.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <libxml/tree.h>#include <clplumbing/ipc.h>#include <clplumbing/cl_log.h> #include <crm/crm.h>#include <xmlutils.h>#include <crm/msg_xml.h>#include <crm/dmalloc_wrapper.h>void dump_array(int log_level, const char *message, const char **array, int depth);xmlNodePtrfind_xml_node_nested(xmlNodePtr root, const char **search_path, int len){ int j; xmlNodePtr child; xmlNodePtr lastMatch; FNIN(); if (root == NULL) { FNRET(NULL); } if(search_path == NULL) { CRM_DEBUG("Will never find NULL :)"); FNRET(NULL); } #ifdef XML_TRACE dump_array(LOG_DEBUG, "Looking for.", search_path, len);#endif child = root->children, lastMatch = NULL; for (j=0; j < len; ++j) { gboolean is_found = FALSE; if (search_path[j] == NULL) { len = j; /* a NULL also means stop searching */ break; } while(child != NULL) { const char * child_name = (const char*)child->name;#ifdef XML_TRACE CRM_DEBUG3("comparing (%s) with (%s).", search_path[j], child->name);#endif if (strcmp(child_name, search_path[j]) == 0) { lastMatch = child; child = lastMatch->children;#ifdef XML_TRACE CRM_DEBUG3("found node (%s) @line (%ld).", search_path[j], xmlGetLineNo(child));#endif is_found = TRUE; break; } child = child->next; } if (is_found == FALSE) {#ifdef XML_TRACE CRM_DEBUG2( "No more siblings left... %s cannot be found.", search_path[j]);#endif break; } } if (j == len && lastMatch != NULL && strcmp(lastMatch->name, search_path[j-1]) == 0) {#ifdef XML_TRACE CRM_DEBUG2("returning node (%s).", xmlGetNodePath(lastMatch));#endif FNRET(lastMatch); } dump_array(LOG_WARNING, "Could not find the full path to the node you specified.", search_path, len); cl_log(LOG_WARNING,"Closest point was node (%s).", xmlGetNodePath(lastMatch)); FNRET(NULL); }const char *get_xml_attr(xmlNodePtr parent, const char *node_name, const char *attr_name, gboolean error){ if(node_name == NULL) { /* get it from the current node */ return get_xml_attr_nested(parent, NULL, 0, attr_name, error); } return get_xml_attr_nested(parent, &node_name, 1, attr_name, error);}const char *get_xml_attr_nested(xmlNodePtr parent, const char **node_path, int length, const char *attr_name, gboolean error){ const char *attr_value = NULL; xmlNodePtr attr_parent = NULL; if(parent == NULL) { cl_log(LOG_ERR, "Can not find attribute %s in NULL parent", attr_name); return NULL; } if(attr_name == NULL || strlen(attr_name) == 0) { cl_log(LOG_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) { cl_log(LOG_ERR, "No node at the path you specified."); return NULL; } } attr_value = xmlGetProp(attr_parent, attr_name); if((attr_value == NULL || strlen(attr_value) == 0) && error) { cl_log(LOG_ERR, "No value present for %s at %s", attr_name, xmlGetNodePath(attr_parent)); return NULL; } return attr_value;}xmlNodePtrset_xml_attr(xmlNodePtr parent, const char *node_name, const char *attr_name, const char *attr_value, gboolean create){ if(node_name == NULL) { /* set it on the current node */ return set_xml_attr_nested(parent, NULL, 0, attr_name, attr_value, create); } return set_xml_attr_nested(parent, &node_name, 1, attr_name, attr_value, create);}xmlNodePtrset_xml_attr_nested(xmlNodePtr parent, const char **node_path, int length, const char *attr_name, const char *attr_value, gboolean create){ xmlAttrPtr result = NULL; xmlNodePtr attr_parent = NULL; xmlNodePtr create_parent = NULL; xmlNodePtr tmp; if(parent == NULL && create == FALSE) { cl_log(LOG_ERR, "Can not set attribute in NULL parent"); return NULL; } if(attr_name == NULL || strlen(attr_name) == 0) { cl_log(LOG_ERR, "Can not set attribute to %s with no name", attr_value); return NULL; } if(length == 0 && parent != NULL) { attr_parent = parent; } else if(length == 0 || node_path == NULL || *node_path == NULL || strlen(*node_path) == 0) { cl_log(LOG_ERR, "Can not create parent to set attribute %s=%s on", attr_name, attr_value); return NULL; } else { attr_parent = find_xml_node_nested(parent, node_path, length); } if(create && attr_parent == NULL) { int j = 0; attr_parent = parent; for (j=0; j < length; ++j) { if (node_path[j] == NULL) { break; } tmp = find_xml_node(attr_parent, node_path[j]); if(tmp == NULL) { attr_parent = create_xml_node(attr_parent, node_path[j]); if(j==0) { create_parent = attr_parent; } } else { attr_parent = tmp; } } } else if(attr_parent == NULL) { cl_log(LOG_ERR, "Can not find parent to set attribute on"); return NULL; } result = set_xml_property_copy(attr_parent, attr_name, attr_value); if(result == NULL) { cl_log(LOG_WARNING, "Could not set %s=%s at %s", attr_name, attr_value, xmlGetNodePath(attr_parent)); } if(create_parent != NULL) { return create_parent; } return parent;}xmlNodePtrfind_xml_node(xmlNodePtr root, const char * search_path){ if(root == NULL) return NULL; return find_xml_node_nested(root, &search_path, 1);}xmlNodePtrfind_entity(xmlNodePtr parent, const char *node_name, const char *id, gboolean siblings){ return find_entity_nested(parent, node_name, NULL, NULL, id, siblings);}xmlNodePtrfind_entity_nested(xmlNodePtr parent, const char *node_name, const char *elem_filter_name, const char *elem_filter_value, const char *id, gboolean siblings){ xmlNodePtr child; FNIN();#ifdef XML_TRACE cl_log(LOG_DEBUG, "Looking for %s elem with id=%s.", node_name, id);#endif while(parent != NULL) {#ifdef XML_TRACE CRM_DEBUG2("examining (%s).", xmlGetNodePath(parent));#endif child = parent->children; while(child != NULL) {#ifdef XML_TRACE CRM_DEBUG2("looking for (%s) [name].", node_name);#endif if (node_name != NULL && strcmp(child->name, node_name) != 0) { #ifdef XML_TRACE CRM_DEBUG3( "skipping entity (%s=%s) [node_name].", xmlGetNodePath(child), child->name);#endif break; } else if (elem_filter_name != NULL && elem_filter_value != NULL) { const char* child_value = (const char*) xmlGetProp(child, elem_filter_name); #ifdef XML_TRACE cl_log(LOG_DEBUG, "comparing (%s) with (%s) [attr_value].", child_value, elem_filter_value);#endif if (strcmp(child_value, elem_filter_value)) {#ifdef XML_TRACE CRM_DEBUG2("skipping entity (%s) [attr_value].", xmlGetNodePath(child));#endif break; } } #ifdef XML_TRACE cl_log(LOG_DEBUG, "looking for entity (%s) in %s.", id, xmlGetNodePath(child));#endif while(child != NULL) {#ifdef XML_TRACE cl_log(LOG_DEBUG, "looking for entity (%s) in %s.", id, xmlGetNodePath(child));#endif xmlChar *child_id = xmlGetProp(child, "id"); if (child_id == NULL) { cl_log(LOG_CRIT, "Entity (%s) has id=NULL..." "Cib not valid!", xmlGetNodePath(child)); } else if (strcmp(id, child_id) == 0) {#ifdef XML_TRACE CRM_DEBUG2("found entity (%s).", id);#endif FNRET(child); } child = child->next; } } if (siblings == TRUE) {#ifdef XML_TRACE CRM_DEBUG("Nothing yet... checking siblings"); #endif parent = parent->next; } else parent = NULL; } cl_log(LOG_INFO, "Couldnt find anything appropriate for %s elem with id=%s.", node_name, id); FNRET(NULL);}voidcopy_in_properties(xmlNodePtr target, xmlNodePtr src){ if(src == NULL) { cl_log(LOG_WARNING, "No node to copy properties from"); } else if (src->properties == NULL) { cl_log(LOG_INFO, "No properties to copy"); } else if (target == NULL) { cl_log(LOG_WARNING, "No node to copy properties into"); } else {#ifndef USE_BUGGY_LIBXML xmlAttrPtr prop_iter = NULL; FNIN(); prop_iter = src->properties; while(prop_iter != NULL) { const char *local_prop_name = prop_iter->name;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -