node macros added (usefule but unfinished)
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
// 1 2 3 4 5 6 7 8
|
// 1 2 3 4 5 6 7 8
|
||||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
// g++ -I../src ../src/xml.cxx address.cxx
|
// g++ -I../../src ../../src/xml.cxx address.cxx
|
||||||
|
|
||||||
#include <xml-cxx/xml.hxx>
|
#include <xml-cxx/xml.hxx>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
32
doc/examples/node_macros.cxx
Normal file
32
doc/examples/node_macros.cxx
Normal file
@@ -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;
|
||||||
|
}
|
50
doc/examples/serialization.cxx
Normal file
50
doc/examples/serialization.cxx
Normal file
@@ -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
|
@endcode
|
||||||
|
|
||||||
@example doc/examples/address.cxx */
|
@example address.cxx */
|
||||||
|
|
||||||
/*! @defgroup serialization Class Serialization
|
/*! @defgroup serialization Class Serialization
|
||||||
|
|
||||||
@@ -201,28 +201,119 @@
|
|||||||
xml::Factory _xmlFactory
|
xml::Factory _xmlFactory
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! Deefine a string for a node name
|
/*! @defgroup xmlConst XML Constant Declarations
|
||||||
/*! Put this macro in the global part of your header files. After
|
|
||||||
declaration of e.g. <code>XML_NODE(tagname)</code> you can use
|
There are macros to help you with declaring constants. Chose a C++
|
||||||
<code>xml::node::tagname</code> as constant std::string with
|
header fiel, where you want to declare constant names for your xml
|
||||||
contents @c "tagname" in your code.
|
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
|
@code
|
||||||
XML_NAME(base);
|
|
||||||
XML_NAME(child);
|
|
||||||
|
|
||||||
int main(int, char**) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode
|
||||||
#define XML_NODE(NAME) \
|
|
||||||
|
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 xml {\
|
||||||
namespace node {\
|
namespace name {\
|
||||||
static const std::string xml::Node NAME(#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 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.
|
//! 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++.
|
/*! 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;
|
typedef std::vector<Node*> List;
|
||||||
Node(std::string name, size_type min=0, size_type max=0) throw();
|
Node(std::string name, size_type min=0, size_type max=0) throw();
|
||||||
Node(const Node& o) throw();
|
Node(const Node& o) throw();
|
||||||
Node& operator=(const Node& o) throw();
|
|
||||||
virtual ~Node() throw();
|
virtual ~Node() throw();
|
||||||
|
virtual Node& operator=(const Node& o) throw();
|
||||||
virtual std::auto_ptr<Node> clone() const throw();
|
virtual std::auto_ptr<Node> clone() const throw();
|
||||||
virtual std::ostream& out(std::ostream& o, unsigned int level=0) const
|
virtual std::ostream& out(std::ostream& o, unsigned int level=0) const
|
||||||
throw();
|
throw();
|
||||||
@@ -626,8 +717,8 @@ namespace xml {
|
|||||||
Node::size_type min=0, Node::size_type max=0) throw();
|
Node::size_type min=0, Node::size_type max=0) throw();
|
||||||
String(std::string name, const std::string& text,
|
String(std::string name, const std::string& text,
|
||||||
Node::size_type min=0, Node::size_type max=0) throw();
|
Node::size_type min=0, Node::size_type max=0) throw();
|
||||||
virtual std::auto_ptr<Node> clone() const throw();
|
|
||||||
virtual ~String() throw() {}
|
virtual ~String() throw() {}
|
||||||
|
virtual std::auto_ptr<Node> clone() const throw();
|
||||||
virtual std::string text() const throw();
|
virtual std::string text() const throw();
|
||||||
virtual String& text(const std::string& txt) throw(tag_expected,
|
virtual String& text(const std::string& txt) throw(tag_expected,
|
||||||
type_mismatch);
|
type_mismatch);
|
||||||
|
@@ -252,6 +252,9 @@ namespace xml {
|
|||||||
it!=o._contents.end(); ++it)
|
it!=o._contents.end(); ++it)
|
||||||
_contents.push_back((*it)->clone(this).release());
|
_contents.push_back((*it)->clone(this).release());
|
||||||
}
|
}
|
||||||
|
Node::~Node() throw() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
//! Assign new node, keep parent.
|
//! Assign new node, keep parent.
|
||||||
/*! The parent remains unchanged, the node does not belong to the
|
/*! The parent remains unchanged, the node does not belong to the
|
||||||
same parent as the source of the copy.
|
same parent as the source of the copy.
|
||||||
@@ -265,9 +268,6 @@ namespace xml {
|
|||||||
it!=o._contents.end(); ++it)
|
it!=o._contents.end(); ++it)
|
||||||
_contents.push_back((*it)->clone(this).release());
|
_contents.push_back((*it)->clone(this).release());
|
||||||
}
|
}
|
||||||
Node::~Node() throw() {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
//! Clones But clears the parent.
|
//! Clones But clears the parent.
|
||||||
/*! You get a new instance of the node, but detached from the
|
/*! You get a new instance of the node, but detached from the
|
||||||
parent. It is then ready to be inserted below a new parent.
|
parent. It is then ready to be inserted below a new parent.
|
||||||
|
Reference in New Issue
Block a user