Virtual Developer Workshop: Containerized Development with Docker
Environment: Win32, MSVC 6.0, STL
Sometimes it is necessary to create XML files from a program in C++. It is possible to use the very powerful set of IXMLDOMxxx interfaces, but this may add unnecessary requirements and overhead to the program. On the other hand, to create XML files from code is not a trivial task in the general case. Even when simple XML files are created, a set of wrapping classes can still be helpful.
To attach attributes to an element, it is necessary to construct a CXmlAttributeSet object and call AssignAttributeSet before StartNode is called. This will ensure all attributes are properly put in the begin tag of the element.
Often XML elements are created in fixed order. A set of macros makes this task extremely easy. To create an element with child elements, use the macro bracket pair START_NODE CLOSE_NODE and create all child elements between these macros. The macro DO_NODE creates an element and immediately puts its end tag. The macros with suffix _A take an additional reference to a CXmlAttributeSet object for the attributes of the node.
When more complex processing is required, CXmlNode objects can be manipulated directly or through a smart pointer wrapper, as shown in the sample.
ofstream ofs("test.xml"); CXmlAttributeSet as("a1","v1"); as.AddAttribute("a2","v2"); UTL_PutXmlHeader(ofs); START_NODE(ofs, "DemoDocument", CXmlNode::EMPTY_DATA); START_NODE_A(ofs, "e1", "t1", as); DO_NODE(ofs, "e11","t11") DO_NODE(ofs, "e12","t12") START_NODE(ofs, "e12","t12") DO_NODE_A(ofs, "e121","t121", CXmlAttributeSet("wee","jee")) DO_NODE(ofs, "answer", 42) DO_NODE(ofs, "NO_PI",3.1514) START_NODE(ofs, "fact","5 3") DO_NODE(ofs, "is ok", true) CLOSE_NODE CLOSE_NODE CLOSE_NODE as.AddAttribute("a3","v3"); DO_NODE_A(ofs, "e2", CXmlNode::EMPTY_DATA, as); CXmlNode * n3 = new CXmlNode(ofs,"e3",CXmlNode::EMPTY_DATA); SmartPtr<CXmlNode> spXml(NULL); n3->StartNode(); spXml = new CXmlNode(ofs,"e31", "t31"); spXml->StartNode(); spXml = NULL; spXml = new CXmlNode(ofs,"e32", "®"); spXml->StartNode(); spXml = NULL; delete n3; CLOSE_NODE
The sample does not catch the exceptions which the CXmlNode class can throw. A professional program would handle these exceptions in an appropriate way.