boost::any instead of macros - first pieces of meta template programming
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
@@ -819,6 +820,8 @@ namespace xml {
|
|||||||
|
|
||||||
class Serialize {
|
class Serialize {
|
||||||
public:
|
public:
|
||||||
|
typedef bool(*FromNodeFunc)(boost::any, const xml::Node&);
|
||||||
|
typedef bool(*ToNodeFunc)(const boost::any, xml::Node&);
|
||||||
//! You must call Serialize::className() if you use this constructor!
|
//! You must call Serialize::className() if you use this constructor!
|
||||||
Serialize() throw();
|
Serialize() throw();
|
||||||
Serialize(const std::string& className) throw();
|
Serialize(const std::string& className) throw();
|
||||||
@@ -872,10 +875,13 @@ namespace xml {
|
|||||||
Serialize& persist(std::string& member,
|
Serialize& persist(std::string& member,
|
||||||
const std::string& name) throw();
|
const std::string& name) throw();
|
||||||
std::ostream& saveXml(std::ostream& os,
|
std::ostream& saveXml(std::ostream& os,
|
||||||
const std::string& name = std::string()) const throw();
|
const std::string& name = std::string())
|
||||||
|
const throw();
|
||||||
std::istream& loadXml(std::istream& is,
|
std::istream& loadXml(std::istream& is,
|
||||||
const std::string& name = std::string());
|
const std::string& name = std::string());
|
||||||
std::string schema() const throw();
|
std::string schema() const throw();
|
||||||
|
static void registerFromNode(FromNodeFunc fromNodeFunc);
|
||||||
|
static void registerToNode(ToNodeFunc toNodeFunc);
|
||||||
protected:
|
protected:
|
||||||
virtual void initXmlMembers();
|
virtual void initXmlMembers();
|
||||||
private:
|
private:
|
||||||
@@ -890,9 +896,8 @@ namespace xml {
|
|||||||
_xmlFactory = schema;
|
_xmlFactory = schema;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename TYPE> void fromNode(TYPE* member, xml::Node& node) {
|
void fromNode(boost::any member, const xml::Node& node);
|
||||||
*member = (TYPE)dynamic_cast<xml::String&>(node);
|
void toNode(const boost::any member, xml::Node& node) const;
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
template<typename TYPE, class ALLOC>
|
template<typename TYPE, class ALLOC>
|
||||||
void fromNode(std::list<TYPE, ALLOC>* member, xml::Node& node) {
|
void fromNode(std::list<TYPE, ALLOC>* member, xml::Node& node) {
|
||||||
@@ -900,13 +905,10 @@ namespace xml {
|
|||||||
for (xml::Node::size_type i(0); i<node.children(); ++i)
|
for (xml::Node::size_type i(0); i<node.children(); ++i)
|
||||||
...
|
...
|
||||||
}*/
|
}*/
|
||||||
template<typename TYPE> void toNode(TYPE* member, xml::Node& node) const {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss<<*member;
|
|
||||||
node.text(ss.str());
|
|
||||||
}
|
|
||||||
std::map<std::string, boost::any> _xmlNames;
|
std::map<std::string, boost::any> _xmlNames;
|
||||||
xml::Factory _xmlFactory;
|
xml::Factory _xmlFactory;
|
||||||
|
static std::set<FromNodeFunc> _fromNode;
|
||||||
|
static std::set<ToNodeFunc> _toNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
218
src/xml.cxx
218
src/xml.cxx
@@ -1016,21 +1016,7 @@ namespace xml {
|
|||||||
|
|
||||||
//============================================================== Serialization
|
//============================================================== Serialization
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
template<> void Serialize::fromNode<Serialize>(Serialize* member,
|
|
||||||
xml::Node& node) {
|
|
||||||
//! @todo improve this (inefficient)
|
|
||||||
std::stringstream ss; // simple but inefficient: rewrite and reread
|
|
||||||
ss<<node;
|
|
||||||
member->loadXml(ss, node.name());
|
|
||||||
}
|
|
||||||
template<> void Serialize::toNode<Serialize>(Serialize* member,
|
|
||||||
xml::Node& node) const {
|
|
||||||
std::stringstream ss;
|
|
||||||
member->saveXml(ss, node.name());
|
|
||||||
xml::Factory factory(node);
|
|
||||||
node = *factory.read(ss);
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Serialize::Serialize() throw() {}
|
Serialize::Serialize() throw() {}
|
||||||
Serialize::Serialize(const std::string& className) throw():
|
Serialize::Serialize(const std::string& className) throw():
|
||||||
@@ -1125,32 +1111,8 @@ namespace xml {
|
|||||||
if (name.size()) node.name(name);
|
if (name.size()) node.name(name);
|
||||||
for (std::map<std::string, boost::any>::const_iterator
|
for (std::map<std::string, boost::any>::const_iterator
|
||||||
it(_xmlNames.begin());
|
it(_xmlNames.begin());
|
||||||
it!=_xmlNames.end(); ++it) {
|
it!=_xmlNames.end(); ++it)
|
||||||
#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \
|
toNode(it->second, node[it->first]);
|
||||||
if (it->second.type()==typeid(TYPE*)) \
|
|
||||||
toNode(boost::any_cast<TYPE*>(it->second), \
|
|
||||||
node[it->first]); \
|
|
||||||
else
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long)
|
|
||||||
throw std::runtime_error(it->first);
|
|
||||||
#undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX
|
|
||||||
}
|
|
||||||
os<<node;
|
os<<node;
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@@ -1161,32 +1123,8 @@ namespace xml {
|
|||||||
std::auto_ptr<xml::Node> node(factory.read(is));
|
std::auto_ptr<xml::Node> node(factory.read(is));
|
||||||
for (std::map<std::string, boost::any>::const_iterator
|
for (std::map<std::string, boost::any>::const_iterator
|
||||||
it(_xmlNames.begin());
|
it(_xmlNames.begin());
|
||||||
it!=_xmlNames.end(); ++it) {
|
it!=_xmlNames.end(); ++it)
|
||||||
#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \
|
fromNode(it->second, (*node)[it->first]);
|
||||||
if (it->second.type()==typeid(TYPE*)) \
|
|
||||||
fromNode(boost::any_cast<TYPE*>(it->second), \
|
|
||||||
(*node)[it->first]); \
|
|
||||||
else
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long)
|
|
||||||
QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long)
|
|
||||||
throw std::runtime_error(it->first);
|
|
||||||
#undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX
|
|
||||||
}
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
std::string Serialize::schema() const throw() {
|
std::string Serialize::schema() const throw() {
|
||||||
@@ -1195,14 +1133,158 @@ namespace xml {
|
|||||||
ss<<*_xmlFactory;
|
ss<<*_xmlFactory;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
template<typename TYPE> bool assignFromNode(boost::any member,
|
||||||
|
const xml::Node& node) {
|
||||||
|
if (member.type()==typeid(TYPE*)) {
|
||||||
|
*boost::any_cast<TYPE*>(member) =
|
||||||
|
(TYPE)dynamic_cast<const xml::String&>(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<typename TYPE> bool assignToNode(const boost::any member,
|
||||||
|
xml::Node& node) {
|
||||||
|
if (member.type()==typeid(TYPE*)) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss<<*boost::any_cast<TYPE*>(member);
|
||||||
|
node.text(ss.str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<> bool assignFromNode<bool>(boost::any member,
|
||||||
|
const xml::Node& node) {
|
||||||
|
if (member.type()==typeid(bool*)) {
|
||||||
|
std::string s(*dynamic_cast<const xml::String&>(node));
|
||||||
|
std::string::size_type
|
||||||
|
start(s.find_first_not_of(" \t\n\r")),
|
||||||
|
end(s.find_last_not_of(" \t\n\r"));
|
||||||
|
if (start==std::string::npos) {
|
||||||
|
*boost::any_cast<bool*>(member) = false;
|
||||||
|
} else {
|
||||||
|
s = s.substr(start, end-start+1);
|
||||||
|
*boost::any_cast<bool*>(member) =
|
||||||
|
s!="0" && s!="false" && s!="no" && s!="off";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<> bool assignToNode<bool>(const boost::any member,
|
||||||
|
xml::Node& node) {
|
||||||
|
if (member.type()==typeid(bool*)) {
|
||||||
|
node.text(*boost::any_cast<bool*>(member)?"true":"false");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<> bool assignFromNode<Serialize>(boost::any member,
|
||||||
|
const xml::Node& node) {
|
||||||
|
if (member.type()==typeid(Serialize*)) {
|
||||||
|
//! @todo improve this (inefficient)
|
||||||
|
std::stringstream ss; // simple but inefficient: rewrite and reread
|
||||||
|
ss<<node;
|
||||||
|
boost::any_cast<Serialize*>(member)->loadXml(ss, node.name());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<> bool assignToNode<Serialize>(const boost::any member,
|
||||||
|
xml::Node& node) {
|
||||||
|
if (member.type()==typeid(Serialize*)) {
|
||||||
|
std::stringstream ss;
|
||||||
|
boost::any_cast<Serialize*>(member)->saveXml(ss, node.name());
|
||||||
|
xml::Factory factory(node);
|
||||||
|
node = *factory.read(ss);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template<typename TYPE, class ALLOC>
|
||||||
|
bool containerFromNode(boost::any member,
|
||||||
|
const xml::Node& node) {
|
||||||
|
LOG("ASSIGN List");
|
||||||
|
}
|
||||||
|
// template<typename TYPE, class ALLOC>
|
||||||
|
// bool assignToNode(const boost::any member, xml::Node& node) {
|
||||||
|
// }
|
||||||
|
void Serialize::registerFromNode(Serialize::FromNodeFunc fromNodeFunc) {
|
||||||
|
if (!_fromNode.size()) { // initial initialization
|
||||||
|
_fromNode.insert(&assignFromNode<Serialize>);
|
||||||
|
_fromNode.insert(&assignFromNode<std::string>);
|
||||||
|
_fromNode.insert(&assignFromNode<float>);
|
||||||
|
_fromNode.insert(&assignFromNode<double>);
|
||||||
|
_fromNode.insert(&assignFromNode<bool>);
|
||||||
|
_fromNode.insert(&assignFromNode<char>);
|
||||||
|
_fromNode.insert(&assignFromNode<signed char>);
|
||||||
|
_fromNode.insert(&assignFromNode<unsigned char>);
|
||||||
|
_fromNode.insert(&assignFromNode<short>);
|
||||||
|
_fromNode.insert(&assignFromNode<signed short>);
|
||||||
|
_fromNode.insert(&assignFromNode<unsigned short>);
|
||||||
|
_fromNode.insert(&assignFromNode<int>);
|
||||||
|
_fromNode.insert(&assignFromNode<signed int>);
|
||||||
|
_fromNode.insert(&assignFromNode<unsigned int>);
|
||||||
|
_fromNode.insert(&assignFromNode<long>);
|
||||||
|
_fromNode.insert(&assignFromNode<signed long>);
|
||||||
|
_fromNode.insert(&assignFromNode<unsigned long>);
|
||||||
|
}
|
||||||
|
_fromNode.insert(fromNodeFunc);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//typedef boost::mpl::vector<Serialize, std::string, float, double, bool, char, signed char, unsigned char, short, signed short, unsigned short, int, signed int, unsigned int, long, signed long, unsigned long> BasicTypes;
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//typedef boost::mpl::vector<Serialize, std::string, float, double, bool, char, signed char, unsigned char, short, signed short, unsigned short, int, signed int, unsigned int, long, signed long, unsigned long> BasicTypes;
|
||||||
|
template<typename TYPE> class RegisterAssignToNode {
|
||||||
|
RegisterAssignToNode() {
|
||||||
|
registerToNode(&assignToNode<TYPE>);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
void Serialize::registerToNode(Serialize::ToNodeFunc toNodeFunc) {
|
||||||
|
if (!_toNode.size()) { // initial initialization
|
||||||
|
_toNode.insert(&assignToNode<Serialize>);
|
||||||
|
_toNode.insert(&assignToNode<std::string>);
|
||||||
|
_toNode.insert(&assignToNode<float>);
|
||||||
|
_toNode.insert(&assignToNode<double>);
|
||||||
|
_toNode.insert(&assignToNode<bool>);
|
||||||
|
_toNode.insert(&assignToNode<char>);
|
||||||
|
_toNode.insert(&assignToNode<signed char>);
|
||||||
|
_toNode.insert(&assignToNode<unsigned char>);
|
||||||
|
_toNode.insert(&assignToNode<short>);
|
||||||
|
_toNode.insert(&assignToNode<signed short>);
|
||||||
|
_toNode.insert(&assignToNode<unsigned short>);
|
||||||
|
_toNode.insert(&assignToNode<int>);
|
||||||
|
_toNode.insert(&assignToNode<signed int>);
|
||||||
|
_toNode.insert(&assignToNode<unsigned int>);
|
||||||
|
_toNode.insert(&assignToNode<long>);
|
||||||
|
_toNode.insert(&assignToNode<signed long>);
|
||||||
|
_toNode.insert(&assignToNode<unsigned long>);
|
||||||
|
}
|
||||||
|
_toNode.insert(toNodeFunc);
|
||||||
|
}
|
||||||
void Serialize::initXmlMembers() {}
|
void Serialize::initXmlMembers() {}
|
||||||
void Serialize::clear() throw() {
|
void Serialize::clear() throw() {
|
||||||
_xmlNames.clear();
|
|
||||||
_xmlFactory.reset();
|
_xmlFactory.reset();
|
||||||
|
_xmlNames.clear();
|
||||||
}
|
}
|
||||||
void Serialize::copy(const Serialize& o) throw() {
|
void Serialize::copy(const Serialize& o) throw() {
|
||||||
clear();
|
clear();
|
||||||
initXmlMembers();
|
initXmlMembers();
|
||||||
}
|
}
|
||||||
|
void Serialize::fromNode(boost::any member, const xml::Node& node) {
|
||||||
|
if (!_fromNode.size()) registerFromNode(&assignFromNode<std::string>);
|
||||||
|
for (std::set<FromNodeFunc>::const_iterator it(_fromNode.begin());
|
||||||
|
it!=_fromNode.end(); ++it)
|
||||||
|
if ((**it)(member, node)) return; // found match
|
||||||
|
throw std::runtime_error(node.name());
|
||||||
|
}
|
||||||
|
void Serialize::toNode(const boost::any member, xml::Node& node) const {
|
||||||
|
if (!_toNode.size()) registerToNode(&assignToNode<std::string>);
|
||||||
|
for (std::set<ToNodeFunc>::const_iterator it(_toNode.begin());
|
||||||
|
it!=_toNode.end(); ++it)
|
||||||
|
if ((**it)(member, node)) return; // found match
|
||||||
|
throw std::runtime_error(node.name());
|
||||||
|
}
|
||||||
|
std::set<Serialize::FromNodeFunc> Serialize::_fromNode;
|
||||||
|
std::set<Serialize::ToNodeFunc> Serialize::_toNode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -115,7 +115,7 @@ class SerializationTest: public CppUnit::TestFixture {
|
|||||||
CPPUNIT_ASSERT_NO_THROW(_a.saveXml(ss));
|
CPPUNIT_ASSERT_NO_THROW(_a.saveXml(ss));
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("<A>\n"
|
CPPUNIT_ASSERT_EQUAL(std::string("<A>\n"
|
||||||
"\t<anInteger>15</anInteger>\n"
|
"\t<anInteger>15</anInteger>\n"
|
||||||
"\t<aBool>1</aBool>\n"
|
"\t<aBool>true</aBool>\n"
|
||||||
"\t<aDouble>123.456</aDouble>\n"
|
"\t<aDouble>123.456</aDouble>\n"
|
||||||
"\t<aString>Hello World</aString>\n"
|
"\t<aString>Hello World</aString>\n"
|
||||||
"\t<anotherString>This is"
|
"\t<anotherString>This is"
|
||||||
@@ -146,7 +146,7 @@ class SerializationTest: public CppUnit::TestFixture {
|
|||||||
void complexLoad() {
|
void complexLoad() {
|
||||||
std::stringstream ss("<A2>\n"
|
std::stringstream ss("<A2>\n"
|
||||||
" <anInteger>-1234</anInteger>\n"
|
" <anInteger>-1234</anInteger>\n"
|
||||||
" <aBool>1</aBool>\n"
|
" <aBool>true</aBool>\n"
|
||||||
" <aDouble>3.141</aDouble>\n"
|
" <aDouble>3.141</aDouble>\n"
|
||||||
" <aString>This is A inside of A2</aString>\n"
|
" <aString>This is A inside of A2</aString>\n"
|
||||||
" <anotherString>Another A-String</anotherString>\n"
|
" <anotherString>Another A-String</anotherString>\n"
|
||||||
@@ -206,7 +206,7 @@ class SerializationTest: public CppUnit::TestFixture {
|
|||||||
CPPUNIT_ASSERT_EQUAL
|
CPPUNIT_ASSERT_EQUAL
|
||||||
(std::string("<A2>\n"
|
(std::string("<A2>\n"
|
||||||
"\t<anInteger>-1234</anInteger>\n"
|
"\t<anInteger>-1234</anInteger>\n"
|
||||||
"\t<aBool>1</aBool>\n"
|
"\t<aBool>true</aBool>\n"
|
||||||
"\t<aDouble>3.141</aDouble>\n"
|
"\t<aDouble>3.141</aDouble>\n"
|
||||||
"\t<aString>This is A inside of A2</aString>\n"
|
"\t<aString>This is A inside of A2</aString>\n"
|
||||||
"\t<anotherString>Another A-String</anotherString>\n"
|
"\t<anotherString>Another A-String</anotherString>\n"
|
||||||
@@ -225,7 +225,7 @@ class SerializationTest: public CppUnit::TestFixture {
|
|||||||
("<C>\n"
|
("<C>\n"
|
||||||
" <a2>\n"
|
" <a2>\n"
|
||||||
" <anInteger>-1234</anInteger>\n"
|
" <anInteger>-1234</anInteger>\n"
|
||||||
" <aBool>1</aBool>\n"
|
" <aBool>true</aBool>\n"
|
||||||
" <aDouble>3.141</aDouble>\n"
|
" <aDouble>3.141</aDouble>\n"
|
||||||
" <aString>This is A inside of A2</aString>\n"
|
" <aString>This is A inside of A2</aString>\n"
|
||||||
" <anotherString>Another A-String</anotherString>\n"
|
" <anotherString>Another A-String</anotherString>\n"
|
||||||
@@ -311,7 +311,7 @@ class SerializationTest: public CppUnit::TestFixture {
|
|||||||
(std::string("<C>\n"
|
(std::string("<C>\n"
|
||||||
"\t<a2>\n"
|
"\t<a2>\n"
|
||||||
"\t\t<anInteger>-1234</anInteger>\n"
|
"\t\t<anInteger>-1234</anInteger>\n"
|
||||||
"\t\t<aBool>1</aBool>\n"
|
"\t\t<aBool>true</aBool>\n"
|
||||||
"\t\t<aDouble>3.141</aDouble>\n"
|
"\t\t<aDouble>3.141</aDouble>\n"
|
||||||
"\t\t<aString>This is A inside of A2</aString>\n"
|
"\t\t<aString>This is A inside of A2</aString>\n"
|
||||||
"\t\t<anotherString>Another A-String</anotherString>\n"
|
"\t\t<anotherString>Another A-String</anotherString>\n"
|
||||||
|
Reference in New Issue
Block a user