more docu; other behaviour for parent
This commit is contained in:
@@ -639,13 +639,13 @@ SOURCE_BROWSER = YES
|
||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
||||
# of functions and classes directly in the documentation.
|
||||
|
||||
INLINE_SOURCES = YES
|
||||
INLINE_SOURCES = NO
|
||||
|
||||
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
|
||||
# doxygen to hide any special comment blocks from generated source code
|
||||
# fragments. Normal C and C++ comments will always remain visible.
|
||||
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
|
||||
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
|
||||
# then for each documented function all documented
|
||||
|
@@ -424,9 +424,10 @@ namespace xml {
|
||||
//----------------------------------------------------------------------------
|
||||
class String: public Node {
|
||||
public:
|
||||
String(std::string name, size_type min=0, size_type max=0) throw();
|
||||
String(std::string name,
|
||||
Node::size_type min=0, Node::size_type max=0) throw();
|
||||
String(std::string name, const std::string& text,
|
||||
size_type min=0, 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 std::string text() const throw();
|
||||
|
101
src/xml.cxx
101
src/xml.cxx
@@ -170,9 +170,9 @@ namespace xml {
|
||||
return second;
|
||||
}
|
||||
//! Convert the attribute to a boolean.
|
||||
/*! @return @c true if the value is set and not equal to one of:
|
||||
@c false @c no @c 0. */
|
||||
Attributes::Value::operator bool() const throw() {
|
||||
/*! @return @c true if the value is set and not equal to one of:
|
||||
@c false @c no @c 0. */
|
||||
return !(second.size()||second=="false"||second=="no"||second=="0");
|
||||
}
|
||||
//! Convert the attribute to a number.
|
||||
@@ -186,7 +186,8 @@ namespace xml {
|
||||
Attributes::Value::operator List() const throw() {
|
||||
return toList();
|
||||
}
|
||||
//! Convert the attribute to a space separated list.
|
||||
//! Convert the attribute to list.
|
||||
/*! @param separators a string containing a list of valid separators */
|
||||
Attributes::List Attributes::Value::toList(const std::string& separators)
|
||||
const throw() {
|
||||
List l;
|
||||
@@ -200,6 +201,8 @@ namespace xml {
|
||||
l.push_back(second.substr(it, pos-it));
|
||||
return l;
|
||||
}
|
||||
//! Get the first value of an attribute containing a list of values.
|
||||
/*! @copydoc xml::Attributes::Value::toList */
|
||||
std::string Attributes::Value::front(const std::string& separators) const
|
||||
throw(empty_attribute_list) {
|
||||
List l(toList(separators));
|
||||
@@ -231,11 +234,15 @@ namespace xml {
|
||||
//----------------------------------------------------------------------------
|
||||
//! Nodes must be given a name.
|
||||
/*! Unnamed nodes are not allowed, therefore there's no default
|
||||
constructor. */
|
||||
constructor.
|
||||
@copydoc xml::Node::limits */
|
||||
Node::Node(std::string name,
|
||||
Node::size_type min, Node::size_type max) throw():
|
||||
_name(name), _parent(0), _min(min), _max(max) {
|
||||
}
|
||||
//! Copy node, reset parent.
|
||||
/*! The parent is reset, the node does not belong to the same parent
|
||||
as the source of the copy. */
|
||||
Node::Node(const Node& o) throw():
|
||||
_attributes(o._attributes), _name(o.name()), _parent(0),
|
||||
_min(o._min), _max(o._max) {
|
||||
@@ -243,10 +250,12 @@ namespace xml {
|
||||
it!=o._contents.end(); ++it)
|
||||
_contents.push_back((*it)->clone(this).release());
|
||||
}
|
||||
//! Assign new node, keep parent.
|
||||
/*! The parent remains unchanged, the node does not belong to the
|
||||
same parent as the source of the copy. */
|
||||
Node& Node::operator=(const Node& o) throw() {
|
||||
_attributes=o._attributes;
|
||||
_name = o.name();
|
||||
_parent = 0;
|
||||
_min = o._min;
|
||||
_max = o._max;
|
||||
for (Contents::const_iterator it(o._contents.begin());
|
||||
@@ -257,11 +266,17 @@ namespace xml {
|
||||
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. */
|
||||
std::auto_ptr<Node> Node::clone() const throw() {
|
||||
std::auto_ptr<Node> res(new Node(*this));
|
||||
res->_parent = 0;
|
||||
return res;
|
||||
}
|
||||
//! Stream XML.
|
||||
/*! Streams the node including all attributes and children. It is
|
||||
formatted with new-lines and tabulator indentation for human
|
||||
readability. */
|
||||
std::ostream& Node::out(std::ostream& o, unsigned int level) const throw() {
|
||||
if (_contents.size()) {
|
||||
o<<std::string(level, '\t')<<'<'<<name();
|
||||
@@ -282,6 +297,8 @@ namespace xml {
|
||||
}
|
||||
return o;
|
||||
}
|
||||
//! Get the textual contents of a node.
|
||||
/*! By default this is the concatenation of all child nodes' texts. */
|
||||
std::string Node::text() const throw() {
|
||||
std::string s;
|
||||
for (Contents::const_iterator it(_contents.begin());
|
||||
@@ -289,17 +306,27 @@ namespace xml {
|
||||
s+=***it;
|
||||
return s;
|
||||
}
|
||||
//! Set a text (forbidden in xml::Node)
|
||||
/*! This method is only useful for child nodes, where it is
|
||||
reimplemented. In xml::Node, the parent of all nodes, it throws
|
||||
xml::tag_expected, since a xml::Node may only contain sub-nodes
|
||||
(formatted as xml-tags) and no plain text. */
|
||||
Node& Node::text(const std::string& txt) throw(tag_expected, type_mismatch) {
|
||||
throw tag_expected(*this, txt);
|
||||
}
|
||||
//! Appends a new node at the end of all children.
|
||||
Node& Node::append(const Node& o) throw(cannot_have_children) {
|
||||
_contents.push_back(o.clone(this).release());
|
||||
return *this;
|
||||
}
|
||||
//! Set a list of attributes.
|
||||
/*! Existing attributes with the same name are overwritten. */
|
||||
Node& Node::set(const Attributes& o) throw() {
|
||||
_attributes.clear();
|
||||
_attributes.insert(o.begin(), o.end());
|
||||
return *this;
|
||||
}
|
||||
//! Clears content and attributes.
|
||||
Node& Node::clear() throw () {
|
||||
for (Contents::const_iterator it(_contents.begin());
|
||||
it!=_contents.end(); ++it)
|
||||
@@ -308,67 +335,131 @@ namespace xml {
|
||||
_attributes.clear();
|
||||
return *this;
|
||||
}
|
||||
//! Get the node's tag name.
|
||||
std::string Node::name() const throw() {
|
||||
return _name;
|
||||
}
|
||||
//! Set minimum number of instances (in a xml::Factory).
|
||||
/*! @copydoc limits */
|
||||
Node& Node::min(Node::size_type m) throw() {
|
||||
_min = m;
|
||||
return *this;
|
||||
}
|
||||
//! Get minimum number of instances (in a xml::Factory).
|
||||
/*! @copydoc limits */
|
||||
Node::size_type Node::min() const throw() {
|
||||
return _min;
|
||||
}
|
||||
//! Set maximum number of instances (in a xml::Factory).
|
||||
/*! @copydoc limits */
|
||||
Node& Node::max(Node::size_type m) throw() {
|
||||
_max = m;
|
||||
return *this;
|
||||
}
|
||||
//! Get maximum number of instances (in a xml::Factory).
|
||||
/*! @copydoc limits */
|
||||
Node::size_type Node::max() const throw() {
|
||||
return _max;
|
||||
}
|
||||
//! @c true if node has a parent.
|
||||
bool Node::isChild() const throw() {
|
||||
return _parent;
|
||||
}
|
||||
//! Get the parent node.
|
||||
Node& Node::parent() const throw(no_parent) {
|
||||
if (!_parent) throw no_parent(*this);
|
||||
return *_parent;
|
||||
}
|
||||
//! Check if a specific attribute is set or not.
|
||||
bool Node::hasAttr(const std::string& name) const throw() {
|
||||
return _attributes.find(name)!=_attributes.end();
|
||||
}
|
||||
//! Declare an attribute template and specify whether it is mandatory
|
||||
/*! Used for setting up attributes in xml::Factory:
|
||||
@code
|
||||
xml::Factory f(xml::Node("root").attr("aname", xml::mandatory);
|
||||
@endcode
|
||||
If a factory reads from a stream, it verifies that only optional
|
||||
or mandatory attributes are given and that mandatory attributes
|
||||
are specified. Otherwise reading throws an exception. */
|
||||
Node& Node::attr(const std::string& name, bool mandatory) throw() {
|
||||
_attributes[name] = mandatory?"xml::mandatory":"xml::optional";
|
||||
return *this;
|
||||
}
|
||||
//! Declare an attribute with given value.
|
||||
/*! When used for setting up attributes in xml::Factory, it
|
||||
specifies an optional attribute with given default value:
|
||||
@code
|
||||
xml::Factory f(xml::Node("root").attr("aname", "avalue");
|
||||
@endcode
|
||||
If a factory reads from a stream and the specified attribute is
|
||||
not given, it is set to @c deflt. */
|
||||
Node& Node::attr(const std::string& name, const std::string& deflt)
|
||||
throw() {
|
||||
_attributes[name] = deflt;
|
||||
return *this;
|
||||
}
|
||||
//! Get an attribute.
|
||||
/*! Returns the attribute's value (empty if the attribute is not set) */
|
||||
std::string Node::attr(const std::string& name) const throw() {
|
||||
Attributes::const_iterator it(_attributes.find(name));
|
||||
if (it!=_attributes.end()) return it->second;
|
||||
return std::string();
|
||||
}
|
||||
//! Get an attribute.
|
||||
/*! Returns the attribute's value (empty if the attribute is not set) */
|
||||
std::string& Node::attr(const std::string& name) throw() {
|
||||
return _attributes[name];
|
||||
}
|
||||
//! Get an attribute.
|
||||
/*! Returns an attribute class or throws an exception if the
|
||||
attribute is not set. This method is useful when you need
|
||||
conversions or other methods as specified in
|
||||
xml::Attributes::Value. */
|
||||
const Attributes::Value Node::attribute(const std::string& name)
|
||||
const throw(attribute_not_available) {
|
||||
Attributes::const_iterator it(_attributes.find(name));
|
||||
if (it!=_attributes.end()) return *it;
|
||||
throw attribute_not_available(*this, name);
|
||||
}
|
||||
//! Get the list of attributes.
|
||||
const Attributes& Node::attributes() const throw() {
|
||||
return _attributes;
|
||||
}
|
||||
//! Get the list of attributes.
|
||||
Attributes& Node::attributes() throw() {
|
||||
return _attributes;
|
||||
}
|
||||
//! Pass a minimal and maximal number for this node in a xml file.
|
||||
/*! Minimal and maximal values are verified when you use the node as
|
||||
a template in a xml::Factory. When the factory reads a stucture
|
||||
from a stream through xml::Factory::read, then all the limits
|
||||
are verified.
|
||||
|
||||
There are several ways to declare the limits.
|
||||
- in the constructor xml::Node::Node
|
||||
- minimum and maximum using method xml::Node::limits
|
||||
- using methods xml::Node::min and xml::Node::max separately
|
||||
|
||||
It is recommended not to use the constructor, but the methods
|
||||
xml::Node::limits, xml::Node::min and xml::Node::max, simply for
|
||||
code readability.
|
||||
|
||||
The number @c 0 means unlimited: xml::Node::min(0) means the
|
||||
value is optional and xml::Node::max(0) means that there is no
|
||||
upper limit. The only exception for this rule is the root
|
||||
element of a structure passed to a xml::Factory which must exist
|
||||
exactly once.
|
||||
|
||||
Default is no limits: <code>0..n</code>,
|
||||
which means that the node is optional and may be instatiated
|
||||
multiple (infinite, unlimited) times. */
|
||||
Node& Node::limits(size_type min, size_type max) throw() {
|
||||
_min = min;
|
||||
_max = max;
|
||||
return *this;
|
||||
}
|
||||
//! Get all children of a given node name
|
||||
Node::List Node::list(const std::string& name) const throw() {
|
||||
List res;
|
||||
for (Contents::const_iterator it(_contents.begin());
|
||||
|
Reference in New Issue
Block a user