node macros added (usefule but unfinished)

master
Marc Wäckerlin 15 years ago
parent 94f5fd4970
commit a9ad45ad4d
  1. 2
      doc/examples/address.cxx
  2. 32
      doc/examples/node_macros.cxx
  3. 50
      doc/examples/serialization.cxx
  4. 121
      src/xml-cxx/xml.hxx
  5. 6
      src/xml.cxx

@ -5,7 +5,7 @@
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// g++ -I../src ../src/xml.cxx address.cxx
// g++ -I../../src ../../src/xml.cxx address.cxx
#include <xml-cxx/xml.hxx>
#include <iostream>

@ -0,0 +1,32 @@
/*! @file
@id $Id$
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// g++ -I../../src ../../src/xml.cxx node_macros.cxx
#include <xml-cxx/xml.hxx>
#include <iostream>
#include <sstream>
XML_NODE(base);
XML_NODE(child);
XML_STRING(element);
int main(int, char**) {
xml::Factory test(*xml::node::base.clone()
<<(*xml::node::child.clone()
<<*xml::string::element.clone()));
std::stringstream ss("<base>\n"
" <child>\n"
" <element>Hello</element>\n"
" </child>\n"
"</base>");
std::auto_ptr<xml::Node> file(test.read(ss));
std::cout<<"The text in element is: "
<<(*file)[xml::name::child][xml::name::element].text()
<<std::endl;
return 0;
}

@ -0,0 +1,50 @@
/*! @file
@id $Id$
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// g++ -I../../src ../../src/xml.cxx node_macros.cxx
#include <xml-cxx/xml.hxx>
#include <iostream>
#include <sstream>
/*
template<class STREAM> class Stream: public STREAM {
public:
virtual ~Stream() {}
template<typename T> virtual Stream& operator%(T& o);
};
template<class STREAM> class IStream: public Stream<STREAM> {
public:
virtual template<typename T> IStream& operator%(T& o) {
operator>>(o);
return *this;
}
};
template<class STREAM> class OStream: public Stream<STREAM> {
public:
virtual template<typename T> OStream& operator%(T& o) {
operator<<(o);
return *this;
}
};
*/
template<class STREAM, typename TYPE>
STREAM& operator%(STREAM& s, TYPE& o);
template<class STREAM, typename TYPE>
STREAM& operator%(STREAM& s, TYPE& o);
class A {
public:
int a;
std::string txt;
};
int main(int, char**) {
return 0;
}

@ -80,7 +80,7 @@
...
@endcode
@example doc/examples/address.cxx */
@example address.cxx */
/*! @defgroup serialization Class Serialization
@ -201,28 +201,119 @@
xml::Factory _xmlFactory
//@}
//! Deefine a string for a node name
/*! Put this macro in the global part of your header files. After
declaration of e.g. <code>XML_NODE(tagname)</code> you can use
<code>xml::node::tagname</code> as constant std::string with
contents @c "tagname" in your code.
/*! @defgroup xmlConst XML Constant Declarations
@code
XML_NAME(base);
XML_NAME(child);
There are macros to help you with declaring constants. Chose a C++
header fiel, where you want to declare constant names for your xml
nodes.
Then for every leaf xml::Node name you will use, call
XML_NODE(name) and for every xml::String call XML_STRING(name).
For every node with children call XML_PARENT(name, child1, child2 ...).
@note Node names must be unique. You can not even use the same
name for a XML_NODE and a XML_STRING declaration.
This code is from the examples:
@include node_macros.cxx
@example node_macros.cxx
The example code is equivalent to:
@code
int main(int, char**) {
xml::Factory test(xml::Node(xml::node::base)
xml::Factory test(xml::Node("base")
<<(xml::Node("child")
<<xml::String("element"));
std::stringstream ss("<base>\n"
" <child>\n"
" <element>Hello</element>\n"
" </child>\n"
"</base>");
std::auto_ptr<xml::Node> file(test.read(ss));
std::cout<<"The element is: "
<<(*file)["child"]["element"]
<<std::endl;
return 0;
}
@endcode */
#define XML_NODE(NAME) \
@endcode
The advantage is the fact that you have no more quoted strings to
cope with. So your potential runtime errors through typos become
compile time errors, which is more robust and easier to find. If
you want to write less code, you are free to use <code>using
namespace xml::name</code> in your C++ implementation files, since
names are more often used than nodes. (@em Never use @c using in a
C++ header file, you would pollute the scope of all the
includers.) */
//@{
//! Define a string for a node name
/*! It is called inside XML_NODE and XML_STRING, so if you work with
these two, you don't have to care about XML_NAME. But you can use
XML_NAME alone if you don't want the other two macros.
@see XML_NODE
@see XML_STRING */
#define XML_NAME(NAME) \
namespace xml {\
namespace name {\
static const std::string NAME(#NAME); \
}\
}
//! Define a constant for a xml::Node and for a string containing its name
/*! Put this macro in the global part of your header files. After
declaration of e.g. <code>XML_NODE(tagname)</code> you can use
<code>xml::node::tagname</code> as constant xml::Node and
<code>xml::name::tagname</code> as a constant std::string with
contents @c "tagname" in your code.
@see XML_STRING same for xml::String
@see XML_NAME called by XML_NODE */
#define XML_NODE(NAME) \
XML_NAME(NAME);\
namespace xml {\
namespace node {\
static const std::string xml::Node NAME(#name);\
static const xml::Node NAME(#NAME);\
}\
}
//! Define a constant for a xml::String and for a string containing its name
/*! Put this macro in the global part of your header files. After
declaration of e.g. <code>XML_STRING(tagname)</code> you can use
<code>xml::string::tagname</code> as constant xml::String and
<code>xml::name::tagname</code> as a constant std::string with
contents @c "tagname" in your code.
@see XML_NODE same for xml::Node
@see XML_NAME called by XML_STRING */
#define XML_STRING(NAME) \
XML_NAME(NAME);\
namespace xml {\
namespace string {\
static const xml::String NAME(#NAME);\
}\
}
//! @todo Define a constant for a xml::Node and for a string containing its name
/*! Put this macro in the global part of your header files. After
declaration of e.g. <code>XML_NODE(tagname)</code> you can use
<code>xml::node::tagname</code> as constant xml::Node and
<code>xml::name::tagname</code> as a constant std::string with
contents @c "tagname" in your code.
@see XML_STRING same for xml::String
@see XML_NAME called by XML_NODE */
#define XML_PARENT(NAME, ...) \
XML_NAME(NAME);\
namespace xml {\
namespace node {\
static const xml::Node NAME(#NAME);\
}\
}
//@}
//! Represents classes for handling C++ access to XML files with strict schema.
/*! The schema ist not presented through xsd, but it can be declared in C++.
@ -564,8 +655,8 @@ namespace xml {
typedef std::vector<Node*> List;
Node(std::string name, size_type min=0, size_type max=0) throw();
Node(const Node& o) throw();
Node& operator=(const Node& o) throw();
virtual ~Node() throw();
virtual Node& operator=(const Node& o) throw();
virtual std::auto_ptr<Node> clone() const throw();
virtual std::ostream& out(std::ostream& o, unsigned int level=0) const
throw();
@ -626,8 +717,8 @@ namespace xml {
Node::size_type min=0, Node::size_type max=0) throw();
String(std::string name, const std::string& text,
Node::size_type min=0, Node::size_type max=0) throw();
virtual std::auto_ptr<Node> clone() const throw();
virtual ~String() throw() {}
virtual std::auto_ptr<Node> clone() const throw();
virtual std::string text() const throw();
virtual String& text(const std::string& txt) throw(tag_expected,
type_mismatch);

@ -252,6 +252,9 @@ namespace xml {
it!=o._contents.end(); ++it)
_contents.push_back((*it)->clone(this).release());
}
Node::~Node() throw() {
clear();
}
//! Assign new node, keep parent.
/*! The parent remains unchanged, the node does not belong to the
same parent as the source of the copy.
@ -265,9 +268,6 @@ namespace xml {
it!=o._contents.end(); ++it)
_contents.push_back((*it)->clone(this).release());
}
Node::~Node() throw() {
clear();
}
//! Clones But clears the parent.
/*! You get a new instance of the node, but detached from the
parent. It is then ready to be inserted below a new parent.

Loading…
Cancel
Save