[Libxmlplusplus-general] Multiple Node types
- From: murrayc t-online de (Murray Cumming)
- To: libxml++ <libxmlplusplus-general lists sourceforge net>
- Subject: [Libxmlplusplus-general] Multiple Node types
- Date: 17 Dec 2002 17:05:02 +0100
I've mostly implemented the separate TextNode class (see the attached
patch), but I can't figure out why examples/dom_build has this output:
<?xml version="1.0"?>
<!DOCTYPE example_xml_doc PUBLIC "" "example_xml_doc.dtd">
<exampleroot><examplechild id="1"><>Some
content</><child_of_child/></examplechild><examplechild
id="2"/></exampleroot>
Notice the <> and </> around "Some Content".
examples/dom_parser seems to work OK.
--
Murray Cumming
murray usa net
www.murrayc.com
? Makefile
? Makefile.in
? aclocal.m4
? autom4te.cache
? config.log
? config.status
? configure
? libtool
? libxml++-1.0.pc
? libxml++.kdevprj
? libxml++.kdevses
? libxmlplusplus_textnode.patch
? temp.diff
? xml++-config
? docs/Makefile
? docs/Makefile.in
? docs/reference/Makefile
? docs/reference/Makefile.in
? examples/Makefile
? examples/Makefile.in
? examples/dom_build/.deps
? examples/dom_build/.libs
? examples/dom_build/Makefile
? examples/dom_build/Makefile.in
? examples/dom_build/example
? examples/dom_parser/.deps
? examples/dom_parser/.libs
? examples/dom_parser/Makefile
? examples/dom_parser/Makefile.in
? examples/dom_parser/example
? examples/sax_exception/.deps
? examples/sax_exception/.libs
? examples/sax_exception/Makefile
? examples/sax_exception/Makefile.in
? examples/sax_exception/example
? examples/sax_parser/.deps
? examples/sax_parser/.libs
? examples/sax_parser/Makefile
? examples/sax_parser/Makefile.in
? examples/sax_parser/example
? libxml++/.deps
? libxml++/.libs
? libxml++/Makefile
? libxml++/Makefile.in
? libxml++/attribute.lo
? libxml++/dtd.lo
? libxml++/libxml++-0.1.la
? libxml++/exceptions/.deps
? libxml++/exceptions/.libs
? libxml++/exceptions/Makefile
? libxml++/exceptions/Makefile.in
? libxml++/exceptions/exception.lo
? libxml++/exceptions/internal_error.lo
? libxml++/exceptions/libexceptions.la
? libxml++/exceptions/parse_error.lo
? libxml++/nodes/.deps
? libxml++/nodes/.libs
? libxml++/nodes/Makefile
? libxml++/nodes/Makefile.am
? libxml++/nodes/Makefile.in
? libxml++/nodes/libnodes.la
? libxml++/nodes/node.lo
? libxml++/nodes/textnode.cc
? libxml++/nodes/textnode.h
? libxml++/nodes/textnode.lo
? libxml++/parsers/.deps
? libxml++/parsers/.libs
? libxml++/parsers/Makefile
? libxml++/parsers/Makefile.in
? libxml++/parsers/domparser.lo
? libxml++/parsers/libparsers.la
? libxml++/parsers/parser.lo
? libxml++/parsers/saxparser.lo
Index: examples/dom_build/main.cc
===================================================================
RCS file: /cvsroot/libxmlplusplus/libxml++/examples/dom_build/main.cc,v
retrieving revision 1.4
diff -u -p -r1.4 main.cc
--- examples/dom_build/main.cc 9 Dec 2002 18:56:22 -0000 1.4
+++ examples/dom_build/main.cc 17 Dec 2002 16:55:05 -0000
@@ -45,7 +45,7 @@ main(int argc, char* argv[])
xmlpp::Node* nodeChild = nodeRoot->add_child("examplechild");
nodeChild->add_attribute("id", "1");
- nodeChild->set_content("Some content");
+ nodeChild->set_child_content("Some content");
nodeChild->add_child("child_of_child");
Index: examples/dom_parser/main.cc
===================================================================
RCS file: /cvsroot/libxmlplusplus/libxml++/examples/dom_parser/main.cc,v
retrieving revision 1.12
diff -u -p -r1.12 main.cc
--- examples/dom_parser/main.cc 9 Dec 2002 21:24:20 -0000 1.12
+++ examples/dom_parser/main.cc 17 Dec 2002 16:55:05 -0000
@@ -35,31 +35,40 @@ void print_indentation(unsigned int inde
void print_node(const xmlpp::Node& node, unsigned int indentation = 0)
{
- print_indentation(indentation);
- std::cout << "Node name = " << node.name() << std::endl;
- print_indentation(indentation);
- std::cout << " line = " << node.line() << std::endl;
-
- if(node.has_content())
+ //If this is a text node:
+ const xmlpp::TextNode* nodeContent = dynamic_cast<const xmlpp::TextNode*>(&node);
+ if(nodeContent)
{
print_indentation(indentation);
- std::cout << "content = " << node.content() << std::endl;
+ std::cout << "content = " << nodeContent->get_content() << std::endl;
}
-
- //Print attributes:
- xmlpp::Node::AttributeList attributes = node.attributes();
- for(xmlpp::Node::AttributeList::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+ else
{
- const xmlpp::Attribute* attribute = *iter;
+ //A normal node:
print_indentation(indentation);
- std::cout << " Attribute " << attribute->name() << " = " << attribute->value() << std::endl;
+ std::cout << "Node name = " << node.name() << std::endl;
}
- //Recurse through child nodes:
- xmlpp::Node::NodeList list = node.children();
- for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ print_indentation(indentation);
+ std::cout << " line = " << node.line() << std::endl;
+
+ if(!nodeContent)
{
- print_node(*(*iter), indentation + 2); //recursive
+ //Print attributes:
+ xmlpp::Node::AttributeList attributes = node.attributes();
+ for(xmlpp::Node::AttributeList::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+ {
+ const xmlpp::Attribute* attribute = *iter;
+ print_indentation(indentation);
+ std::cout << " Attribute " << attribute->name() << " = " << attribute->value() << std::endl;
+ }
+
+ //Recurse through child nodes:
+ xmlpp::Node::NodeList list = node.children();
+ for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ print_node(*(*iter), indentation + 2); //recursive
+ }
}
}
Index: libxml++/libxml++.h
===================================================================
RCS file: /cvsroot/libxmlplusplus/libxml++/libxml++/libxml++.h,v
retrieving revision 1.8
diff -u -p -r1.8 libxml++.h
--- libxml++/libxml++.h 17 Dec 2002 15:22:43 -0000 1.8
+++ libxml++/libxml++.h 17 Dec 2002 16:55:05 -0000
@@ -12,6 +12,7 @@
#include <libxml++/parsers/domparser.h>
#include <libxml++/parsers/saxparser.h>
#include <libxml++/nodes/node.h>
+#include <libxml++/nodes/textnode.h>
#include <libxml++/attribute.h>
#endif //__LIBXMLCPP_H
Index: libxml++/nodes/node.cc
===================================================================
RCS file: /cvsroot/libxmlplusplus/libxml++/libxml++/nodes/node.cc,v
retrieving revision 1.1
diff -u -p -r1.1 node.cc
--- libxml++/nodes/node.cc 17 Dec 2002 15:22:45 -0000 1.1
+++ libxml++/nodes/node.cc 17 Dec 2002 16:55:05 -0000
@@ -5,7 +5,9 @@
*/
#include <libxml++/nodes/node.h>
+#include <libxml++/nodes/textnode.h>
#include <libxml++/exceptions/internal_error.h>
+#include <iostream>
namespace xmlpp {
@@ -25,16 +27,9 @@ Node::Node(const std::string& name, int
_initialized = true;
}
-Node::Node(const std::string& name, const std::string& content)
- : _name(std::string()), _content(content), _line(0) {
- _initialized = true;
-}
-
Node::Node(const Node* from)
: _initialized(false), _name(from->name()), _line(from->line())
{
- set_content(from->_content);
-
for(AttributeList::const_iterator curattr = from->attributes().begin();
curattr != from->attributes().end();
++curattr)
@@ -46,6 +41,7 @@ Node::Node(const Node* from)
curnode != from->children().end();
++curnode)
{
+ //TODO: Create the appropriate type:
add_child(new Node(*curnode));
}
@@ -59,9 +55,6 @@ Node::Node(xmlNodePtr node)
_line = XML_GET_LINE(node);
- if(XML_GET_CONTENT(node))
- set_content((char*) XML_GET_CONTENT(node));
-
for(xmlAttrPtr attr = node->properties;
attr;
attr = attr->next)
@@ -73,7 +66,14 @@ Node::Node(xmlNodePtr node)
child;
child = child->next)
{
- add_child(new Node(child));
+ Node* pChild = 0;
+
+ if(child->type == XML_TEXT_NODE)
+ pChild = new TextNode(child);
+ else
+ pChild = new Node(child);
+
+ add_child(pChild);
}
}
@@ -95,11 +95,6 @@ Node::~Node() {
}
}
-void Node::set_content(const std::string& content)
-{
- _content = content;
-}
-
Node::NodeList Node::children(const std::string& name)
{
if(name.empty())
@@ -136,12 +131,11 @@ Node* Node::add_child(Node* node) {
return node;
}
-Node* Node::add_content(const std::string& content) {
- Node* tmp;
-
- tmp = new Node(std::string(), content);
+TextNode* Node::add_content(const std::string& content)
+{
+ TextNode* tmp = new TextNode(std::string(), content);
- return add_child(tmp);
+ return static_cast<TextNode*>(add_child(tmp));
}
void Node::remove_child(Node* node)
@@ -229,26 +223,32 @@ int Node::line() const
bool Node::has_content() const
{
- return !(content().empty());
+ return get_child_content() != 0;
}
-const std::string& Node::content() const
+const TextNode* Node::get_child_content() const
{
- if(!_content.empty())
- return _content;
+ const NodeList& listNodes = children("text");
+ if(listNodes.empty())
+ return 0;
else
{
- const NodeList& listNodes = children("text");
- if(listNodes.empty())
- return _content; //Which will be empty. We could return "" but this would break because we return a const std::string&. I wish we didn't. murrayc.
- else
- {
- Node* nodeContent = *(listNodes.begin());
- return nodeContent->content();
- }
+ const Node* nodeContent = *(listNodes.begin());
+ return static_cast<const TextNode*>(nodeContent);
}
}
+TextNode* Node::get_child_content()
+{
+ NodeList listNodes = children("text");
+ if(listNodes.empty())
+ return 0;
+ else
+ {
+ Node* nodeContent = *(listNodes.begin());
+ return static_cast<TextNode*>(nodeContent);
+ }
+}
const Node::AttributeList& Node::attributes() const
{
@@ -261,13 +261,15 @@ const Attribute* Node::attribute(const s
}
void Node::write(xmlDocPtr doc, xmlNodePtr parent) const
-{
+{
xmlNodePtr node = 0;
if(!parent)
node = doc->children = xmlNewDocNode(doc, NULL /* ns */, (xmlChar*) name().c_str(), 0);
else
{
+ //std::cout << "Node::write: xmlNewChild(): " << _name << std::endl;
+
node = xmlNewChild(parent, NULL /* ns */, (xmlChar*) name().c_str(), 0);
if(!node)
throw internal_error("xmlNewChild() returned NULL");
@@ -275,11 +277,6 @@ void Node::write(xmlDocPtr doc, xmlNodeP
if(node)
{
- if( !_content.empty() )
- {
- xmlNodeSetContent(node, (const xmlChar*)_content.c_str());
- }
-
//Add the attributes:
for(AttributeList::const_iterator iter = _attributes_list.begin();
iter != _attributes_list.end();
@@ -295,10 +292,21 @@ void Node::write(xmlDocPtr doc, xmlNodeP
++iter)
{
//Add the nodes to this parent node:
+
+ //write() is a virtual function, implemented differently for each node type.
(*iter)->write(doc, node);
}
}
+}
+
+void Node::set_child_content(const std::string& content)
+{
+ TextNode* node = get_child_content();
+ if(!node)
+ node = add_content(content);
+ else
+ node->set_content(content);
}
} // namespace xmlpp
Index: libxml++/nodes/node.h
===================================================================
RCS file: /cvsroot/libxmlplusplus/libxml++/libxml++/nodes/node.h,v
retrieving revision 1.1
diff -u -p -r1.1 node.h
--- libxml++/nodes/node.h 17 Dec 2002 15:22:45 -0000 1.1
+++ libxml++/nodes/node.h 17 Dec 2002 16:55:05 -0000
@@ -15,6 +15,8 @@
namespace xmlpp {
+class TextNode;
+
/** Represents XML Nodes.
* You should never new or delete Nodes. The Parser will create and manage them for you.
*/
@@ -27,7 +29,6 @@ public:
explicit Node(const std::string& name);
Node(const std::string& name, int line);
- Node(const std::string& name, const std::string& content);
explicit Node(const Node* from);
explicit Node(xmlNodePtr node);
~Node();
@@ -37,15 +38,18 @@ public:
int line() const;
bool has_content() const;
- const std::string& content() const;
- void set_content(const std::string& content);
-
+
+ TextNode* get_child_content();
+ const TextNode* get_child_content() const;
+ TextNode* add_content(const std::string& name = std::string());
+ void set_child_content(const std::string& content);
+
NodeList children(const std::string& name = std::string());
const NodeList children(const std::string& name = std::string()) const;
Node* add_child(const std::string& name);
Node* add_child(Node* node);
- Node* add_content(const std::string& name = std::string());
+
/** Remove the child node.
* @param node The child node to remove. This Node will be deleted and therefore unusable after calling this method.
@@ -62,7 +66,7 @@ public:
*/
void remove_attribute(const std::string& name);
- void write(xmlDocPtr doc, xmlNodePtr parent = 0) const;
+ virtual void write(xmlDocPtr doc, xmlNodePtr parent = 0) const;
private:
Attribute* add_attribute(xmlAttrPtr attr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]