Scenario: 1. Sometimes you need to store key-value pairs When configuring global settings for the software. 2. When there is not much configuration information, the database is too heavyweight, and text files are not well-coded for utf8, that is, Chinese content. XML files are the best choice at this time.
// Here the libxml2-2.7.1 version library is used
# Include <iostream> # include <string. h> # include <libxml/xmlmemory. h> # include <libxml/parser. h> # include <libxml/parserInternals. h> # include <libxml/HTMLparser. h> # include <libxml/HTMLtree. h> # include <libxml/tree. h> # include <libxml/xpath. h> # include <libxml/debugXML. h> # include <libxml/xmlerror. h> # include "libxml/encoding. h "// # include <tchar. h> using namespace std; void UpdateNodeValue (xmlNode * node, const Char * value) {xmlChar * xml_value = xmlCharStrdup (value); xmlNodeSetContent (node, xml_value); xmlFree (xml_value);} void UpdateAttrValue (xmlNode * node, const char * attr_name, const char * value) {xmlChar * xml_prop_name = xmlCharStrdup (attr_name); xmlChar * xml_prop_value = values (value); xmlSetProp (node, handler, xml_prop_value); xmlFree (xml_prop_value ); xmlFree (xml_prop_name);} xmlXPathObj EctPtr GetXPathObject (xmlDocPtr doc, const char * key) {// get the xpath context xmlXPathContextPtr context = xmlXPathNewContext (doc); if (! Context) {return NULL;} // get the xpath Object Pointer xmlChar * xml_key = xmlCharStrdup (key); xmlXPathObjectPtr result = xmlXPathEvalExpression (xml_key, context); xmlFree (xml_key ); // release the xpath context xmlXPathFreeContext (context); // if (! Result) {return NULL;} // The result is NULL if (! Result | xmlXPathNodeSetIsEmpty (result-> nodesetval) {return NULL;} return result;} // update the node content void UpdateXmlNodeValue (xmlDocPtr doc, const char * key, const char * value) {xmlXPathObjectPtr result = GetXPathObject (doc, key); if (! Result) {return;} xmlNodeSetPtr nodeset = result-> nodesetval; for (int I = 0; I <nodeset-> nodeNr; I ++) {// update the node value UpdateNodeValue (nodeset-> nodeTab [I], value);} xmlXPathFreeObject (result);} // update the node attribute value void UpdateXmlNodeAttr (xmlDocPtr doc, const char * key, const char * attr_name, const char * value) {xmlXPathObjectPtr result = GetXPathObject (doc, key); if (! Result) {return;} xmlNodeSetPtr nodeset = result-> nodesetval; for (int I = 0; I <nodeset-> nodeNr; I ++) {UpdateAttrValue (nodeset-> nodeTab [I], attr_name, value);} xmlXPathFreeObject (result);} xmlDocPtr BeginUpdate (const char * xml_path) {xmlInitParser (); xmlDocPtr doc = xmlParseFile (xml_path); return doc;} void EndUpdate (xmlDocPtr doc, const char * out_path) {xmlSaveFileEnc (out_path, doc, "UTF-8"); xmlFreeDoc (doc ); xmlCleanupParser ();} int main (int argc, char ** argv) {xmlDocPtr doc = BeginUpdate ("test. xml "); // UpdateXmlNodeValue (doc," // toolbarwindow [@ name] "," goodbye "); UpdateXmlNodeValue (doc," // selectwindow "," goodbye "); updateXmlNodeAttr (doc, "/// toolbarwindow/rect [@ x]", "x", "100"); EndUpdate (doc, "out. xml "); return 0 ;}
// Test example [test. xml]
<xml><selectwindow>It is a select object window</selectwindow><toolbarwindow name="toolbar" width="200">It is a toolbar.<rect x="4" y="5"/></toolbarwindow ></xml>
Running result [out. xml]:
<?xml version="1.0" encoding="UTF-8"?><xml><selectwindow>goodbye</selectwindow><toolbarwindow name="toolbar" width="200">It is a toolbar.<rect x="100" y="5"/></toolbarwindow></xml>
Problem:
If this program executes this statement: UpdateXmlNodeValue (doc, "// toolbarwindow [@ name]", "goodbye ");
Result:
<?xml version="1.0" encoding="UTF-8"?><xml><selectwindow>goodbye</selectwindow><toolbarwindow name="toolbar" width="200">goodbye</toolbarwindow></xml>
<Rect x = "4" y = "5"/> is also deleted. If you are interested, you can modify the problem.