2 * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
3 * are covered by the GNU Lesser General Public License, which should be
4 * included with libxml++ as the file COPYING.
8 #include <libxml/debugXML.h>
10 static XMLNode *readnode(xmlNodePtr);
11 static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int);
20 XMLTree::XMLTree(const string &fn)
28 XMLTree::XMLTree(const XMLTree * from)
30 _filename = from->filename();
31 _root = new XMLNode(*from->root());
32 _compression = from->compression();
43 XMLTree::set_compression(int c)
66 xmlKeepBlanksDefault(0);
68 doc = xmlParseFile(_filename.c_str());
73 _root = readnode(xmlDocGetRootElement(doc));
80 XMLTree::read_buffer(const string & buffer)
91 doc = xmlParseMemory((char *) buffer.c_str(), buffer.length());
96 _root = readnode(xmlDocGetRootElement(doc));
103 XMLTree::write(void) const
106 XMLNodeList children;
109 xmlKeepBlanksDefault(0);
110 doc = xmlNewDoc((xmlChar *) "1.0");
111 xmlSetDocCompressMode(doc, _compression);
112 writenode(doc, _root, doc->children, 1);
113 result = xmlSaveFormatFileEnc(_filename.c_str(), doc, "UTF-8", 1);
124 XMLTree::debug(FILE* out) const
127 XMLNodeList children;
129 xmlKeepBlanksDefault(0);
130 doc = xmlNewDoc((xmlChar *) "1.0");
131 xmlSetDocCompressMode(doc, _compression);
132 writenode(doc, _root, doc->children, 1);
133 xmlDebugDumpDocument (out, doc);
138 XMLTree::write_buffer(void) const
140 static string retval;
144 XMLNodeList children;
146 xmlKeepBlanksDefault(0);
147 doc = xmlNewDoc((xmlChar *) "1.0");
148 xmlSetDocCompressMode(doc, _compression);
149 writenode(doc, _root, doc->children, 1);
150 xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len);
160 XMLNode::XMLNode(const string & n)
161 : _name(n), _is_content(false), _content(string())
165 XMLNode::XMLNode(const string & n, const string & c)
166 :_name(n), _is_content(true), _content(c)
170 XMLNode::XMLNode(const XMLNode& from)
172 XMLPropertyList props;
173 XMLPropertyIterator curprop;
175 XMLNodeIterator curnode;
178 set_content(from.content());
180 props = from.properties();
181 for (curprop = props.begin(); curprop != props.end(); ++curprop) {
182 add_property((*curprop)->name().c_str(), (*curprop)->value());
185 nodes = from.children();
186 for (curnode = nodes.begin(); curnode != nodes.end(); ++curnode) {
187 add_child_copy(**curnode);
193 XMLNodeIterator curchild;
194 XMLPropertyIterator curprop;
196 for (curchild = _children.begin(); curchild != _children.end(); ++curchild) {
200 for (curprop = _proplist.begin(); curprop != _proplist.end(); ++curprop) {
206 XMLNode::set_content(const string & c)
220 XMLNode::child (const char *name) const
222 /* returns first child matching name */
224 XMLNodeConstIterator cur;
230 for (cur = _children.begin(); cur != _children.end(); ++cur) {
231 if ((*cur)->name() == name) {
240 XMLNode::children(const string& n) const
242 /* returns all children matching name */
244 XMLNodeConstIterator cur;
250 _selected_children.clear();
252 for (cur = _children.begin(); cur != _children.end(); ++cur) {
253 if ((*cur)->name() == n) {
254 _selected_children.insert(_selected_children.end(), *cur);
258 return _selected_children;
262 XMLNode::add_child(const char * n)
264 return add_child_copy(XMLNode (n));
268 XMLNode::add_child_nocopy (XMLNode& n)
270 _children.insert(_children.end(), &n);
274 XMLNode::add_child_copy(const XMLNode& n)
276 XMLNode *copy = new XMLNode (n);
277 _children.insert(_children.end(), copy);
282 XMLNode::add_content(const string & c)
284 return add_child_copy(XMLNode (string(), c));
288 XMLNode::property(const char * n)
291 map<string,XMLProperty*>::iterator iter;
293 if ((iter = _propmap.find(ns)) != _propmap.end()) {
301 XMLNode::property(const string & ns)
303 map<string,XMLProperty*>::iterator iter;
305 if ((iter = _propmap.find(ns)) != _propmap.end()) {
313 XMLNode::add_property(const char * n, const string & v)
316 if(_propmap.find(ns) != _propmap.end()){
320 XMLProperty *tmp = new XMLProperty(ns, v);
326 _propmap[tmp->name()] = tmp;
327 _proplist.insert(_proplist.end(), tmp);
333 XMLNode::add_property(const char * n, const char * v)
336 return add_property(n, vs);
340 XMLNode::remove_property(const string & n)
342 if (_propmap.find(n) != _propmap.end()) {
343 _proplist.remove(_propmap[n]);
349 XMLNode::remove_nodes(const string & n)
351 XMLNodeIterator i = _children.begin();
354 while (i != _children.end()) {
357 if ((*i)->name() == n) {
365 XMLNode::remove_nodes_and_delete(const string & n)
367 XMLNodeIterator i = _children.begin();
370 while (i != _children.end()) {
373 if ((*i)->name() == n) {
381 XMLProperty::XMLProperty(const string &n, const string &v)
387 XMLProperty::~XMLProperty()
392 readnode(xmlNodePtr node)
394 string name, content;
400 name = (char *) node->name;
403 tmp = new XMLNode(name);
405 for (attr = node->properties; attr; attr = attr->next) {
407 if (attr->children) {
408 content = (char *) attr->children->content;
410 tmp->add_property((char *) attr->name, content);
414 tmp->set_content((char *) node->content);
416 tmp->set_content(string());
419 for (child = node->children; child; child = child->next) {
420 tmp->add_child_nocopy (*readnode(child));
427 writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = 0)
429 XMLPropertyList props;
430 XMLPropertyIterator curprop;
431 XMLNodeList children;
432 XMLNodeIterator curchild;
436 node = doc->children = xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0);
438 node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0);
441 if (n->is_content()) {
442 node->type = XML_TEXT_NODE;
443 xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), n->content().length());
446 props = n->properties();
447 for (curprop = props.begin(); curprop != props.end(); ++curprop) {
448 xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), (xmlChar *) (*curprop)->value().c_str());
451 children = n->children();
452 for (curchild = children.begin(); curchild != children.end(); ++curchild) {
453 writenode(doc, *curchild, node);