In the program, we often use tree controls, while persistence and displaying a tree, using an XML file is relatively appropriate. This article provides two functions, one is based on the XML file generated tree, the other opposite, saving the contents of the tree to the XML file. There are also many examples in its actual side, but most of them are more complicated, or the language is used. This article uses VC6.0 SP5 to write, parse XML with MSXML4.0; the code is relatively simple, and there is no excessive thing, such as the node data type, to remove dysfunction and highlight ideas.
Const char root [] = "// root"; // Hypothesis root is XML root node / / -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------- // 1: Load the XML document into the tree control / / / --------- -------------------------------------------- Bool Loadxmltotree (LPTSTSTSTSTSTSTSTR XMLFileName , CTreeCtrl * pTree) {CoInitialize (NULL); IXMLDOMDocument2Ptr pXMLDom; HRESULT hr = pXMLDom.CreateInstance (__ uuidof (DOMDocument40)); if (FAILED (hr)) {return FALSE;} pXMLDom-> async = VARIANT_FALSE; // default - True,
/ / Load XML file IF (pxmldom-> load (_variant_t (xmlfilename))! = Variant_true) {return false;}
Ixmldomnodeptr prootnode = pxmldom-> selectsinglenode (root); // get root node if (prootnode == null) Return False;
LPTSTR SROOT = _COM_UTIL :: ConvertBSTRTRTSTRING (ProotNode-> getnodename ()); htreeItem root = ptree-> insertitem (_t (sroot)); // Add root node to the tree
XMLNODetReenode (root, prootnode, ptree); // This function is below
PXMLDOM = NULL; ProotNode = null; counitialize (); return true;}
/ / -------------------------------------------------------------------------------------------- ------ // Recursively add all child nodes under a node to the tree // ----------------------------- ------------------------- void Xmlnodetreenode (HtreeItem ParentItem, IxmLDomnodePtr PXMLNode, CTreeCtrl * Ptree) {if (! wcscmp (pxmlnode-> getnodetypeString () , L "text")) // Node type Meaning, please refer to MSDNRETURN;
Ixmldomnodelistptr pxmlnodelist = pxmlnode-> getChildNodes (); long count = pxmlnodelist-> getLength (); // child node number if (count == 0) {// No child node, set the parent node LPTSTSTSNODE = _COM_UTIL: : ConvertBSTRToString (pXmlNode-> getnodeName ()); pTree-> SetItemText (parentItem, sNode); return;} for (int i = 0; i
-------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ---------------------------- // 2: Save CTreeCtrl to XML // --------- ------------------- BOOL SaveTreeToXml (CTreeCtrl * pTree, LPTSTR xmlFileName) {CoInitialize (NULL); IXMLDOMDocument2Ptr pXMLDom; HRESULT hr = pXMLDom.CreateInstance (__ uuidof (DOMDocument40)) ; if (Failed (HR)) {RETURN FALSE;} PXMLDOM-> async = variant_false; // default-true
// adds header information IXMLDOMProcessingInstructionPtr pPI = NULL; pPI = pXMLDom-> createProcessingInstruction ( "xml", "version = '1.0' encoding = 'UTF-8'"); _ variant_t vNullVal; vNullVal.vt = VT_NULL; pXMLDom-> insertBefore (PPI, VNULLVAL);
HTREEITEM rootItem = pTree-> GetRootItem (); // Add the root of the tree DomIXMLDOMNodePtr pRootNode = pXMLDom-> createNode (_variant_t ((short) NODE_ELEMENT), _ bstr_t (pTree-> GetItemText (rootItem)), _ bstr_t ( "")) PXMLDOM-> appendchild (prootnode);
TreenoDetoxmlNode (Ptree, rootItem, PXMLDOM, ProotNode); // This function is below
PXMLDOM-> Save (_VARIANT_T (XMLFileName); Return True;}
/ / -------------------------------------------------------------------------------------------- ------ // Recursively outputs a node in the tree and all child nodes thereof to XML, the principle is the same. // Enter: Tree and root node; XML and root nodes. Here is the DOM // object to createenode, the function name exceeds 255, so use extern "c" // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {if (! ptree-> itemhaschildren (parentItem)) {return;}
IXMLDOMNodePtr pChildNode; HTREEITEM hChildItem = pTree-> GetChildItem (parentItem); // get all child nodes while the parentItem (! HChildItem = NULL) {CString szText = pTree-> GetItemText (hChildItem);! If (pTree-> ItemHasChildren (hChildItem )) // is a leaf- {pXmlNode-> appendChild (pXMLDom-> createTextNode (_bstr_t (szText))); // puttext} else // there sub sub {pChildNode = pXMLDom-> createNode (_variant_t ((short) NODE_ELEMENT ), _ bstr_t (_BSTR_T (Sztext)), _ bstr_t (""));
Pxmlnode-> appendchild (pchildnode); TreenodetoxmlNode (Ptree, HchildItem, PXMLDOM, PCHILDNODE); recursion} hchildItem = ptree-> getNextItem (HchildItem, TVGn_Next);}
}
Here, CTREECTRL is regarded as a parameter, in practical applications, generally, they may be a certain member, so you can bring so many parameters.
-------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
When XML DOM is constructed in the program, there will be no indent, but all nodes are in one line, (unless you write indentation code while constructing the DOM, it will make the program make it difficult to understand), just like the front Savetreetox ML You will find that the XML file written is only one line, all things are in this line. This requires a function that converts this line of XML into a constant format. Extern "C" void feedtabs (ixmldomdocument2ptr pdoc, ixmldomnodeptr pParentNode, IXmLDomnodeptr prefnode, int Tabs) {cstring s ("/ n"); if (prefNode) // first sub-/ n / t / t / t.. (tabs) {for (int i = 0; i
Extern "C" void wellformxml (ixmldomdocument2ptr pdoc, ixmldomnodeptr pparentnode, int tabs) {if (pParentnode-> HaschildNodes ()) {// first child plus "/N/t.. / t ' ) Ixmldomnodeptr pfirstchild = pParentnode-> getFirstChild (); feedtabs (PDOC, PParentNode, Pfirstchild, Tabs);
// The last child is added "/N/t.." FeedTabs (PDOC, PParentNode, Null, Tabs);
// Recursive children Wellformxml (PDOC, Pfirstchild, Tabs 1);
// recursive Brothers IXMLDOMNodePtr pNextSib = pParentNode-> GetnextSibling (); if (pNextSib) {IXMLDOMNodePtr pGrandParent = pParentNode-> GetparentNode ();! If ((pGrandParent = NULL) && wcscmp (pNextSib-> GetnodeTypeString (), L "text ")) {// before adding" /N/t.. "before the next brother" FeedTabs (PDOC, PGRANDParent, PNEXTSIB, TABS-1); WellFormXML (PDOC, PNEXTSIB, TABS) }}}
Since these functions can be tested because they are not associated with GUI, these functions can be tested:
#include "afx.h" #import
int main (void) {CoInitialize (NULL); IXMLDOMDocument2Ptr pXMLDom; HRESULT hr = pXMLDom.CreateInstance (__ uuidof (DOMDocument40)); if (FAILED (hr)) {printf ( "Fail to CreateInstance!"); return 1;} pXMLDom -> async = variant_false; if (pxmldom-> load (_variant_t ("one_line.xml"))))! = variant_true) // load your XML {Printf ("Fail to Load XML File!"); return 1;}
IXmlDomnodeptr rootnode = pxmldom-> selectsinglenode ("// root"); // Your XML root node if (rootnode == null) Return 1;
Wellformxml (PXMLDOM, Rootnode, 1); PXMLDOM-> Save (_VARIANT_T ("Well_Formed.xml"); // To save XML
PXMLDOM = NULL; rootnode = null; couninitialize ();
Return 0;}