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 static XMLNodeList retval;
245 XMLNodeConstIterator cur;
251 retval.erase(retval.begin(), retval.end());
253 for (cur = _children.begin(); cur != _children.end(); ++cur) {
254 if ((*cur)->name() == n) {
255 retval.insert(retval.end(), *cur);
263 XMLNode::add_child(const char * n)
265 return add_child_copy(XMLNode (n));
269 XMLNode::add_child_nocopy (XMLNode& n)
271 _children.insert(_children.end(), &n);
275 XMLNode::add_child_copy(const XMLNode& n)
277 XMLNode *copy = new XMLNode (n);
278 _children.insert(_children.end(), copy);
283 XMLNode::add_content(const string & c)
285 return add_child_copy(XMLNode (string(), c));
289 XMLNode::property(const char * n)
292 if (_propmap.find(ns) == _propmap.end()) {
300 XMLNode::add_property(const char * n, const string & v)
303 if(_propmap.find(ns) != _propmap.end()){
307 XMLProperty *tmp = new XMLProperty(ns, v);
313 _propmap[tmp->name()] = tmp;
314 _proplist.insert(_proplist.end(), tmp);
320 XMLNode::add_property(const char * n, const char * v)
323 return add_property(n, vs);
327 XMLNode::remove_property(const string & n)
329 if (_propmap.find(n) != _propmap.end()) {
330 _proplist.remove(_propmap[n]);
336 XMLNode::remove_nodes(const string & n)
338 XMLNodeIterator i = _children.begin();
341 while (i != _children.end()) {
344 if ((*i)->name() == n) {
352 XMLNode::remove_nodes_and_delete(const string & n)
354 XMLNodeIterator i = _children.begin();
357 while (i != _children.end()) {
360 if ((*i)->name() == n) {
368 XMLProperty::XMLProperty(const string &n, const string &v)
374 XMLProperty::~XMLProperty()
379 readnode(xmlNodePtr node)
381 string name, content;
387 name = (char *) node->name;
390 tmp = new XMLNode(name);
392 for (attr = node->properties; attr; attr = attr->next) {
394 if (attr->children) {
395 content = (char *) attr->children->content;
397 tmp->add_property((char *) attr->name, content);
401 tmp->set_content((char *) node->content);
403 tmp->set_content(string());
406 for (child = node->children; child; child = child->next) {
407 tmp->add_child_nocopy (*readnode(child));
414 writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = 0)
416 XMLPropertyList props;
417 XMLPropertyIterator curprop;
418 XMLNodeList children;
419 XMLNodeIterator curchild;
423 node = doc->children = xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0);
425 node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0);
428 if (n->is_content()) {
429 node->type = XML_TEXT_NODE;
430 xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), n->content().length());
433 props = n->properties();
434 for (curprop = props.begin(); curprop != props.end(); ++curprop) {
435 xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), (xmlChar *) (*curprop)->value().c_str());
438 children = n->children();
439 for (curchild = children.begin(); curchild != children.end(); ++curchild) {
440 writenode(doc, *curchild, node);