Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /DD4hep/DDCore/src/XML/XMLElements.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #ifdef DD4HEP_USE_TINYXML
0016 #include <XML/tinyxml.h>
0017 #else
0018 #include <xercesc/util/Xerces_autoconf_config.hpp>
0019 #include <xercesc/util/XMLString.hpp>
0020 #include <xercesc/dom/DOMElement.hpp>
0021 #include <xercesc/dom/DOMDocument.hpp>
0022 #include <xercesc/dom/DOMNodeList.hpp>
0023 #include <xercesc/dom/DOM.hpp>
0024 #include <XML/config.h>
0025 #endif
0026 
0027 #include <XML/XMLElements.h>
0028 #include <XML/Printout.h>
0029 #include <XML/XMLTags.h>
0030 
0031 // C/C++ include files
0032 #include <cstdio>
0033 #include <iostream>
0034 #include <map>
0035 #include <stdexcept>
0036 #include <string>
0037 #include <utility>
0038 #include <vector>
0039 
0040 using namespace dd4hep::xml;
0041 static const size_t INVALID_NODE = ~0U;
0042 static int          s_float_precision = -1;
0043 
0044 // Forward declarations
0045 namespace dd4hep {
0046   std::pair<int, double> _toInteger(const std::string& value);
0047   std::pair<int, double> _toFloatingPoint(const std::string& value);
0048   void   _toDictionary(const std::string& name, const std::string& value, const std::string& typ);
0049   std::string _getEnviron(const std::string& env);
0050 }
0051 
0052 // Static storage
0053 namespace {
0054   bool s_resolve_environment = true;
0055   std::string _checkEnviron(const std::string& env)  {
0056     if ( s_resolve_environment )  {
0057       std::string r = dd4hep::_getEnviron(env);
0058       return r.empty() ? env : r;
0059     }
0060     return env;
0061   }
0062 }
0063 
0064 // Shortcuts
0065 #define _D(x)   Xml(x).d
0066 #define _E(x)   Xml(x).e
0067 #define _N(x)   Xml(x).n
0068 #define _L(x)   Xml(x).l
0069 #define _XE(x)  Xml(x).xe
0070 
0071 #ifdef DD4HEP_USE_TINYXML
0072 #define ELEMENT_NODE_TYPE TiXmlNode::ELEMENT
0073 #define getTagName          Value
0074 #define getTextContent      GetText
0075 #define getName             Name
0076 #define getValue            Value
0077 #define getNodeValue        Value
0078 #define getNodeType         Type
0079 #define setNodeValue        SetValue
0080 #define getParentNode       Parent()->ToElement
0081 #define getAttributeNode(x) AttributeNode(x)
0082 #define appendChild         LinkEndChild
0083 #define getOwnerDocument    GetDocument
0084 #define getDocumentElement  RootElement
0085 #define getDocumentURI      Value
0086 
0087 /// Union to ease castless object access in TinyXML
0088 union Xml {
0089   Xml(const void* ptr) : p(ptr) {}
0090   const void* p;
0091   TiXmlNode* n;
0092   TiXmlElement* e;
0093   TiXmlAttribute* a;
0094   TiXmlDocument* d;
0095   XmlElement* xe;
0096 };
0097 
0098 namespace {
0099   XmlElement* node_first(XmlElement* e, const Tag_t& t) {
0100     if ( t.str()=="*" ) return e ? (XmlElement*)_E(e)->FirstChildElement() : 0;
0101     return e ? (XmlElement*)_E(e)->FirstChildElement(t.str()) : 0;
0102   }
0103   size_t node_count(XmlElement* elt, const Tag_t& t) {
0104     size_t cnt = 0;
0105     TiXmlElement* e = Xml(elt).e;
0106     if ( t.str()=="*" )
0107       for(e=e->FirstChildElement();e; e=e->NextSiblingElement()) ++cnt;
0108     else
0109       for(e=e->FirstChildElement(t.str());e; e=e->NextSiblingElement(t.str())) ++cnt;
0110     return cnt;
0111   }
0112 }
0113 XmlChar* dd4hep::xml::XmlString::replicate(const XmlChar* c) {
0114   return c ? ::strdup(c) : 0;
0115 }
0116 XmlChar* dd4hep::xml::XmlString::transcode(const char* c)    {return c ? ::strdup(c) : 0;
0117 }
0118 void dd4hep::xml::XmlString::release(char** p) {
0119   if(p && *p)  {::free(*p); *p=0;}
0120 }
0121 size_t dd4hep::xml::XmlString::length(const char* p)  {
0122   return p ? ::strlen(p) : 0;
0123 }
0124 
0125 #else
0126 #define ELEMENT_NODE_TYPE xercesc::DOMNode::ELEMENT_NODE
0127 
0128 /// Union to ease castless object access when using XercesC
0129 union Xml {
0130   Xml(const void* ptr)
0131     : p(ptr) {
0132   }
0133   const void* p;
0134   xercesc::DOMNode* n;
0135   xercesc::DOMAttr* a;
0136   xercesc::DOMElement* e;
0137   xercesc::DOMDocument* d;
0138   xercesc::DOMNodeList* l;
0139   XmlElement* xe;
0140 };
0141 
0142 XmlChar* dd4hep::xml::XmlString::replicate(const XmlChar* c) {
0143   return xercesc::XMLString::replicate(c);
0144 }
0145 char* dd4hep::xml::XmlString::transcode(const XmlChar* c) {
0146   return xercesc::XMLString::transcode(c);
0147 }
0148 XmlChar* dd4hep::xml::XmlString::transcode(const char* c) {
0149   return xercesc::XMLString::transcode(c);
0150 }
0151 void dd4hep::xml::XmlString::release(XmlChar** p) {
0152   return xercesc::XMLString::release(p);
0153 }
0154 void dd4hep::xml::XmlString::release(char** p) {
0155   return xercesc::XMLString::release(p);
0156 }
0157 size_t dd4hep::xml::XmlString::length(const char* p)  {
0158   return p ? xercesc::XMLString::stringLen(p) : 0;
0159 }
0160 size_t dd4hep::xml::XmlString::length(const XmlChar* p)  {
0161   return p ? xercesc::XMLString::stringLen(p) : 0;
0162 }
0163 
0164 namespace {
0165   size_t node_count(XmlElement* e, const Tag_t& t) {
0166     size_t cnt = 0;
0167     if ( e )  {
0168       const std::string& tag = t;
0169       xercesc::DOMElement *ee = Xml(e).e;
0170       if ( ee )  {
0171         for(xercesc::DOMElement* elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) {
0172           if ( elt->getParentNode() == ee )   {
0173             std::string child_tag = _toString(elt->getTagName());
0174             if ( tag == "*" || child_tag == tag ) ++cnt;
0175           }
0176         }
0177       }
0178     }
0179     return cnt;
0180   }
0181   XmlElement* node_first(XmlElement* e, const Tag_t& t) {
0182     if ( e )  {
0183       const std::string& tag = t;
0184       xercesc::DOMElement* ee = Xml(e).e;
0185       if ( ee )  {
0186         for(xercesc::DOMElement* elt=ee->getFirstElementChild(); elt; elt=elt->getNextElementSibling()) {
0187           if ( elt->getParentNode() == ee )   {
0188             if ( tag == "*" ) return _XE(elt);
0189             std::string child_tag = _toString(elt->getTagName());
0190             if ( child_tag == tag ) return _XE(elt);
0191           }
0192         }
0193       }
0194     }
0195     return 0;
0196   }
0197 }
0198 
0199 /// Convert XML char to std::string
0200 std::string dd4hep::xml::_toString(const XmlChar *toTranscode) {
0201   char *buff = XmlString::transcode(toTranscode);
0202   std::string tmp(buff == 0 ? "" : buff);
0203   XmlString::release(&buff);
0204   if ( tmp.length()<3 ) return tmp;
0205   if ( !(tmp[0] == '$' && tmp[1] == '{') ) return tmp;
0206   tmp = _checkEnviron(tmp);
0207   return tmp;
0208 }
0209 #endif
0210 
0211 namespace {
0212   Attribute attribute_node(XmlElement* n, const XmlChar* t) {
0213     return Attribute(_E(n)->getAttributeNode(t));
0214   }
0215   const XmlChar* attribute_value(Attribute a) {
0216     return Xml(a).a->getValue();
0217   }
0218 #if 0
0219   int node_type(XmlNode* n) {return Xml(n).n->getNodeType();}
0220   int node_type(Handle_t n) {return Xml(n.ptr()).n->getNodeType();}
0221 #endif
0222 }
0223 
0224 /// Change floating point precision on conversion to string
0225 int dd4hep::xml::set_float_precision(int precision)    {
0226   int tmp = s_float_precision;
0227   s_float_precision = precision;
0228   return tmp;
0229 }
0230 
0231 /// Access floating point precision on conversion to string
0232 int dd4hep::xml::get_float_precision()    {
0233   return s_float_precision;
0234 }
0235 
0236 /// Convert attribute value to string
0237 std::string dd4hep::xml::_toString(Attribute attr) {
0238   if (attr)
0239     return _toString(attribute_value(attr));
0240   return "";
0241 }
0242 
0243 template <typename T> static inline std::string __to_string(T value, const char* fmt) {
0244   char text[128];
0245   ::snprintf(text, sizeof(text), fmt, value);
0246   return text;
0247 }
0248 
0249 /// Do-nothing version. Present for completeness and argument interchangeability
0250 std::string dd4hep::xml::_toString(const char* s) {
0251   if ( !s || *s == 0 ) return "";
0252   else if ( !(*s == '$' && *(s+1) == '{') ) return s;
0253   return _checkEnviron(s);
0254 }
0255 
0256 /// Do-nothing version. Present for completeness and argument interchangeability
0257 std::string dd4hep::xml::_toString(const std::string& s) {
0258   if ( s.length() < 3 || s[0] != '$' ) return s;
0259   else if ( !(s[0] == '$' && s[1] == '{') ) return s;
0260   return _checkEnviron(s);
0261 }
0262 
0263 /// Format unsigned long integer to string with arbitrary format
0264 std::string dd4hep::xml::_toString(unsigned long v, const char* fmt) {
0265   return __to_string(v, fmt);
0266 }
0267 
0268 /// Format unsigned integer (32 bits) to string with arbitrary format
0269 std::string dd4hep::xml::_toString(unsigned int v, const char* fmt) {
0270   return __to_string(v, fmt);
0271 }
0272 
0273 /// Format signed integer (32 bits) to string with arbitrary format
0274 std::string dd4hep::xml::_toString(int v, const char* fmt) {
0275   return __to_string(v, fmt);
0276 }
0277 
0278 /// Format signed long integer to string with arbitrary format
0279 std::string dd4hep::xml::_toString(long v, const char* fmt)   {
0280   return __to_string(v, fmt);
0281 }
0282 
0283 /// Format single procision float number (32 bits) to string with arbitrary format
0284 std::string dd4hep::xml::_toString(float v, const char* fmt) {
0285   if ( s_float_precision >= 0 )   {
0286     char format[32];
0287     ::snprintf(format, sizeof(format), "%%.%de", s_float_precision);
0288     return __to_string(v, format);
0289   }
0290   return __to_string(v, fmt);
0291 }
0292 
0293 /// Format double procision float number (64 bits) to string with arbitrary format
0294 std::string dd4hep::xml::_toString(double v, const char* fmt) {
0295   if ( s_float_precision >= 0 )   {
0296     char format[32];
0297     ::snprintf(format, sizeof(format), "%%.%de", s_float_precision);
0298     return __to_string(v, format);
0299   }
0300   return __to_string(v, fmt);
0301 }
0302 
0303 /// Convert Strng_t to std::string
0304 std::string dd4hep::xml::_toString(const Strng_t& s)   {
0305   return _toString(Tag_t(s));
0306 }
0307 
0308 /// Convert Tag_t to std::string
0309 std::string dd4hep::xml::_toString(const Tag_t& s)     {
0310   return s.str();
0311 }
0312 
0313 /// Format pointer to string with arbitrary format
0314 std::string dd4hep::xml::_ptrToString(const void* v, const char* fmt) {
0315   return __to_string(v, fmt);
0316 }
0317 
0318 long dd4hep::xml::_toLong(const XmlChar* value) {
0319   if (value) {
0320     std::string s = _toString(value);
0321     return dd4hep::_toInteger(s).second;
0322   }
0323   return -1;
0324 }
0325 
0326 unsigned long dd4hep::xml::_toULong(const XmlChar* value) {
0327   long val = _toLong(value);
0328   if ( val >= 0 ) return (unsigned long) val;
0329   std::string s = _toString(value);
0330   throw std::runtime_error("dd4hep: Severe error during expression evaluation of " + s);
0331 }
0332 
0333 int dd4hep::xml::_toInt(const XmlChar* value)   {
0334   return (int)_toLong(value);
0335 }
0336 
0337 unsigned int dd4hep::xml::_toUInt(const XmlChar* value) {
0338   return (unsigned int)_toULong(value);
0339 }
0340 
0341 bool dd4hep::xml::_toBool(const XmlChar* value) {
0342   if (value)   {
0343     std::string s = _toString(value);
0344     char   c = ::toupper(s[0]);
0345     if ( c == 'T' || c == '1' ) return true;
0346     if ( c == 'F' || c == '0' ) return false;
0347     return _toInt(value) != 0;
0348   }
0349   return false;
0350 }
0351 
0352 float dd4hep::xml::_toFloat(const XmlChar* value) {
0353   if (value)   {
0354     std::string s = _toString(value);
0355     return (float) dd4hep::_toFloatingPoint(s).second;
0356   }
0357   return 0.0;
0358 }
0359 
0360 double dd4hep::xml::_toDouble(const XmlChar* value) {
0361   if (value)   {
0362     std::string s = _toString(value);
0363     return dd4hep::_toFloatingPoint(s).second;
0364   }
0365   return 0.0;
0366 }
0367 
0368 void dd4hep::xml::_toDictionary(const XmlChar* name, const XmlChar* value) {
0369   std::string n = _toString(name).c_str(), v = _toString(value);
0370   dd4hep::_toDictionary(n, v, "number");
0371 }
0372 
0373 /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0374 void dd4hep::xml::_toDictionary(const XmlChar* name, const Strng_t& s)   {
0375   return _toDictionary(name, s.ptr());
0376 }
0377 
0378 /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
0379 void dd4hep::xml::_toDictionary(const XmlChar* name, const Tag_t& t)   {
0380   return _toDictionary(name, t.ptr());
0381 }
0382 
0383 template <typename T>
0384 void dd4hep::xml::_toDictionary(const XmlChar* name, T value)   {
0385   Strng_t item = _toString(value);
0386   const XmlChar* item_value = item;
0387   _toDictionary(name, item_value);
0388 }
0389 
0390 #ifndef DD4HEP_USE_TINYXML
0391 template void dd4hep::xml::_toDictionary(const XmlChar* name, const char* value);
0392 #endif
0393 template void dd4hep::xml::_toDictionary(const XmlChar* name, const Tag_t& value);
0394 template void dd4hep::xml::_toDictionary(const XmlChar* name, const Strng_t& value);
0395 template void dd4hep::xml::_toDictionary(const XmlChar* name, const std::string& value);
0396 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned long value);
0397 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned int value);
0398 template void dd4hep::xml::_toDictionary(const XmlChar* name, unsigned short value);
0399 template void dd4hep::xml::_toDictionary(const XmlChar* name, int value);
0400 template void dd4hep::xml::_toDictionary(const XmlChar* name, long value);
0401 template void dd4hep::xml::_toDictionary(const XmlChar* name, short value);
0402 template void dd4hep::xml::_toDictionary(const XmlChar* name, float value);
0403 template void dd4hep::xml::_toDictionary(const XmlChar* name, double value);
0404 
0405 /// Evaluate string constant using environment stored in the evaluator
0406 std::string dd4hep::xml::getEnviron(const std::string& env)   {
0407   return dd4hep::_getEnviron(env);
0408 }
0409 
0410 /// Enable/disable environment resolution when parsing strings
0411 bool dd4hep::xml::enableEnvironResolution(bool new_value)   {
0412   bool tmp = s_resolve_environment;
0413   s_resolve_environment = new_value;
0414   return tmp;
0415 }
0416 
0417 template <typename B>
0418 static inline std::string i_add(const std::string& a, B b) {
0419   std::string r = a;
0420   r += b;
0421   return r;
0422 }
0423 
0424 Strng_t dd4hep::xml::operator+(const Strng_t& a, const std::string& b) {
0425   return _toString(a.ptr()) + b;
0426 }
0427 
0428 Strng_t dd4hep::xml::operator+(const std::string& a, const Strng_t& b) {
0429   return a + _toString(b.ptr());
0430 }
0431 
0432 Strng_t dd4hep::xml::operator+(const Strng_t& a, const char* b) {
0433   return _toString(a.ptr()) + b;
0434 }
0435 
0436 Strng_t dd4hep::xml::operator+(const char* a, const Strng_t& b) {
0437   return std::string(a) + _toString(b.ptr());
0438 }
0439 
0440 Strng_t dd4hep::xml::operator+(const Strng_t& a, const Strng_t& b) {
0441   return _toString(a.ptr()) + _toString(b.ptr());
0442 }
0443 
0444 Tag_t dd4hep::xml::operator+(const Tag_t& a, const char* b) {
0445   std::string res = a.str() + b;
0446   return Tag_t(res);
0447 }
0448 
0449 Tag_t dd4hep::xml::operator+(const char* a, const Tag_t& b) {
0450   std::string res = a + b.str();
0451   return Tag_t(res);
0452 }
0453 
0454 Tag_t dd4hep::xml::operator+(const Tag_t& a, const Strng_t& b) {
0455   std::string res = a.str() + _toString(b);
0456   return Tag_t(res);
0457 }
0458 
0459 Tag_t dd4hep::xml::operator+(const Tag_t& a, const std::string& b) {
0460   std::string res = a.str() + b;
0461   return Tag_t(res);
0462 }
0463 
0464 #ifndef DD4HEP_USE_TINYXML
0465 Strng_t dd4hep::xml::operator+(const Strng_t& a, const XmlChar* b) {
0466   std::string res = _toString(a.ptr()) + _toString(b);
0467   return Tag_t(res);
0468 }
0469 
0470 Strng_t dd4hep::xml::operator+(const XmlChar* a, const Strng_t& b) {
0471   std::string res = _toString(a) + _toString(b.ptr());
0472   return Tag_t(res);
0473 }
0474 
0475 Strng_t dd4hep::xml::operator+(const XmlChar* a, const std::string& b) {
0476   std::string res = _toString(a) + b;
0477   return Tag_t(res);
0478 }
0479 
0480 Strng_t dd4hep::xml::operator+(const std::string& a, const XmlChar* b) {
0481   std::string res = a + _toString(b);
0482   return Tag_t(res);
0483 }
0484 
0485 Tag_t dd4hep::xml::operator+(const Tag_t& a, const XmlChar* b) {
0486   std::string res = a.str() + _toString(b);
0487   return Tag_t(res);
0488 }
0489 
0490 Strng_t& Strng_t::operator=(const XmlChar* s) {
0491   if (m_xml)
0492     XmlString::release (&m_xml);
0493   m_xml = s ? XmlString::replicate(s) : 0;
0494   return *this;
0495 }
0496 #endif
0497 
0498 Strng_t& Strng_t::operator=(const char* s) {
0499   if (m_xml)
0500     XmlString::release (&m_xml);
0501   m_xml = s ? XmlString::transcode(s) : 0;
0502   return *this;
0503 }
0504 
0505 Strng_t& Strng_t::operator=(const Strng_t& s) {
0506   if (this != &s) {
0507     if (m_xml)
0508       XmlString::release (&m_xml);
0509     m_xml = XmlString::replicate(s.m_xml);
0510   }
0511   return *this;
0512 }
0513 
0514 Strng_t& Strng_t::operator=(const std::string& s) {
0515   if (m_xml)
0516     XmlString::release (&m_xml);
0517   m_xml = XmlString::transcode(s.c_str());
0518   return *this;
0519 }
0520 
0521 Tag_t& Tag_t::operator=(const Tag_t& s) {
0522   if (this != &s) {
0523     m_str = s.m_str;
0524     if (m_xml)
0525       XmlString::release (&m_xml);
0526     m_xml = XmlString::transcode(m_str.c_str());
0527   }
0528   return *this;
0529 }
0530 
0531 Tag_t& Tag_t::operator=(const char* s) {
0532   if (m_xml)
0533     XmlString::release (&m_xml);
0534   if (s) {
0535     m_xml = XmlString::transcode(s);
0536     m_str = s;
0537   }
0538   else {
0539     m_xml = 0;
0540     m_str = "";
0541   }
0542   return *this;
0543 }
0544 
0545 Tag_t& Tag_t::operator=(const Strng_t& s) {
0546   if (m_xml)  {
0547     XmlString::release (&m_xml);
0548   }
0549   char* ns = s.m_xml ? XmlString::transcode(s.m_xml) : 0;
0550   m_str = ns ? ns : "";
0551   m_xml = XmlString::transcode(m_str.c_str());
0552   if (ns)  {
0553     XmlString::release(&ns);
0554   }
0555   return *this;
0556 }
0557 
0558 Tag_t& Tag_t::operator=(const std::string& s) {
0559   if (m_xml)
0560     XmlString::release (&m_xml);
0561   m_xml = XmlString::transcode(s.c_str());
0562   m_str = s;
0563   return *this;
0564 }
0565 
0566 /// Copy constructor
0567 NodeList::NodeList(const NodeList& copy)
0568   : m_tag(copy.m_tag), m_node(copy.m_node), m_ptr(0)
0569 {
0570   reset();
0571 }
0572 
0573 /// Initializing constructor
0574 NodeList::NodeList(XmlElement* node, const XmlChar* tag_value)
0575   : m_tag(tag_value), m_node(node), m_ptr(0)
0576 {
0577   reset();
0578 }
0579 
0580 /// Default destructor
0581 NodeList::~NodeList() {
0582 }
0583 
0584 /// Reset the nodelist
0585 XmlElement* NodeList::reset() {
0586   return m_ptr=node_first(m_node,m_tag);
0587 }
0588 
0589 /// Advance to next element
0590 XmlElement* NodeList::next() const {
0591 #ifdef DD4HEP_USE_TINYXML
0592   if ( m_tag.str()=="*" )
0593     return m_ptr =_XE(m_ptr ? _E(m_ptr)->NextSiblingElement() : 0);
0594   return m_ptr = _XE(m_ptr ? _E(m_ptr)->NextSiblingElement(m_tag.str()) : 0);
0595 #else
0596   xercesc::DOMElement *elt = Xml(m_ptr).e;
0597   for(elt=elt->getNextElementSibling(); elt; elt=elt->getNextElementSibling()) {
0598     if ( m_tag.str() == "*" ) return m_ptr=Xml(elt).xe;
0599     std::string child_tag = _toString(elt->getTagName());
0600     if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe;
0601   }
0602   return m_ptr=0;
0603 #endif
0604 }
0605 
0606 /// Go back to previous element
0607 XmlElement* NodeList::previous() const {
0608 #ifdef DD4HEP_USE_TINYXML
0609   if ( m_tag.str()=="*" )
0610     return m_ptr = _XE(m_ptr ? _E(m_ptr)->PreviousSiblingElement() : 0);
0611   return m_ptr = _XE(m_ptr ? _E(m_ptr)->PreviousSiblingElement(m_tag) : 0);
0612 #else
0613   xercesc::DOMElement *elt = Xml(m_ptr).e;
0614   for(elt=elt->getPreviousElementSibling(); elt; elt=elt->getPreviousElementSibling()) {
0615     if ( m_tag.str()=="*" ) return m_ptr=Xml(elt).xe;
0616     std::string child_tag = _toString(elt->getTagName());
0617     if ( child_tag == m_tag ) return m_ptr=Xml(elt).xe;
0618   }
0619   return m_ptr=0;
0620 #endif
0621 }
0622 
0623 /// Assignment operator
0624 NodeList& NodeList::operator=(const NodeList& l) {
0625   if (this != &l) {
0626     m_tag = l.m_tag;
0627     m_node = l.m_node;
0628     reset();
0629   }
0630   return *this;
0631 }
0632 
0633 /// Unicode text access to the element's tag. Tis must be wrong ....
0634 const XmlChar* Handle_t::rawTag() const {
0635   return _E(m_node)->getTagName();
0636 }
0637 
0638 /// Unicode text access to the element's text
0639 const XmlChar* Handle_t::rawText() const {
0640   return _E(m_node)->getTextContent();
0641 }
0642 
0643 /// Unicode text access to the element's value
0644 const XmlChar* Handle_t::rawValue() const {
0645   return _N(m_node)->getNodeValue();
0646 }
0647 
0648 /// Clone the DOMelement - with the option of a deep copy
0649 Handle_t Handle_t::clone(XmlDocument* new_doc) const {
0650   if (m_node) {
0651 #ifdef DD4HEP_USE_TINYXML
0652     if ( new_doc ) {}
0653     if ( _N(m_node)->Type() == ELEMENT_NODE_TYPE ) {
0654       XmlElement* e = _XE(_N(m_node)->Clone()->ToElement());
0655       if ( e ) return e;
0656     }
0657     throw std::runtime_error("TiXml: Handle_t::clone: Invalid source handle type [No element type].");
0658 #else
0659     return Elt_t(_D(new_doc)->importNode(_E(m_node), true));
0660 #endif
0661   }
0662   throw std::runtime_error("Xml: Handle_t::clone: Invalid source handle.");
0663 }
0664 
0665 /// Access the element's parent element
0666 Handle_t Handle_t::parent() const {
0667   return Elt_t(m_node ? _N(m_node)->getParentNode() : 0);
0668 }
0669 
0670 /// Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
0671 Attribute Handle_t::attr_nothrow(const XmlChar* tag_value) const {
0672   return attribute_node(m_node, tag_value);
0673 }
0674 
0675 /// Check for the existence of a named attribute
0676 bool Handle_t::hasAttr(const XmlChar* tag_value) const {
0677   return m_node && 0 != _E(m_node)->getAttributeNode(tag_value);
0678 }
0679 
0680 /// Retrieve a collection of all attributes of this DOM element
0681 std::vector<Attribute> Handle_t::attributes() const {
0682   std::vector < Attribute > attrs;
0683   if (m_node) {
0684 #ifdef DD4HEP_USE_TINYXML
0685     for(TiXmlAttribute* a=_E(m_node)->FirstAttribute(); a; a=a->Next())
0686       attrs.emplace_back(Attribute(a));
0687 #else
0688     xercesc::DOMNamedNodeMap* l = _E(m_node)->getAttributes();
0689     for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i) {
0690       xercesc::DOMNode* attr_node = l->item(i);
0691       attrs.emplace_back(Attribute(attr_node));
0692     }
0693 #endif
0694   }
0695   return attrs;
0696 }
0697 
0698 size_t Handle_t::numChildren(const XmlChar* t, bool throw_exception) const {
0699   size_t n = node_count(m_node, t);
0700   if (n == INVALID_NODE && !throw_exception)
0701     return 0;
0702   else if (n != INVALID_NODE)
0703     return n;
0704   std::string msg = "Handle_t::numChildren: ";
0705   if (m_node)
0706     msg += "Element [" + tag() + "] has no children of type '" + _toString(t) + "'";
0707   else
0708     msg += "Element [INVALID] has no children of type '" + _toString(t) + "'";
0709   throw std::runtime_error(msg);
0710 }
0711 
0712 /// Remove a single child node identified by its handle from the tree of the element
0713 Handle_t Handle_t::child(const XmlChar* t, bool throw_exception) const {
0714   Elt_t e = node_first(m_node, t);
0715   if (e || !throw_exception)
0716     return e;
0717   std::string msg = "Handle_t::child: ";
0718   if (m_node)
0719     msg += "Element [" + tag() + "] has no child of type '" + _toString(t) + "'";
0720   else
0721     msg += "Element [INVALID]. Cannot remove child of type: '" + _toString(t) + "'";
0722   throw std::runtime_error(msg);
0723 }
0724 
0725 NodeList Handle_t::children(const XmlChar* tag_value) const {
0726   return NodeList(m_node, tag_value);
0727 }
0728 
0729 /// Append a DOM element to the current node
0730 void Handle_t::append(Handle_t e) const {
0731   _N(m_node)->appendChild(_N(e.ptr()));
0732 }
0733 
0734 /// Remove a single child node identified by its handle from the tree of the element
0735 Handle_t Handle_t::remove(Handle_t node) const {
0736 #ifdef DD4HEP_USE_TINYXML
0737   bool e = (m_node && node.ptr() ? _N(m_node)->RemoveChild(_N(node.ptr())) : false);
0738 #else
0739   Elt_t e = Elt_t(m_node && node.ptr() ? _N(m_node)->removeChild(_N(node.ptr())) : 0);
0740 #endif
0741   if (e)
0742     return node.ptr();
0743   std::string msg = "Handle_t::remove: ";
0744   if (m_node && node.ptr())
0745     msg += "Element [" + tag() + "] has no child of type '" + node.tag() + "'";
0746   else if (node)
0747     msg += "Element [INVALID]. Cannot remove child of type: '" + node.tag() + "'";
0748   else if (!node)
0749     msg += "Element [INVALID]. Cannot remove [INVALID] child. Big Shit!!!!";
0750 
0751   throw std::runtime_error(msg);
0752 }
0753 
0754 /// Remove children with a given tag name from the DOM node
0755 void Handle_t::removeChildren(const XmlChar* tag_value) const {
0756 #ifdef DD4HEP_USE_TINYXML
0757   for(TiXmlNode* n=_E(m_node)->FirstChildElement(tag_value);n;n=_E(m_node)->FirstChildElement(tag_value))
0758     n->RemoveChild(n);
0759 #else
0760   xercesc::DOMElement* e = _E(m_node);
0761   xercesc::DOMNodeList* l = e->getElementsByTagName(tag_value);
0762   for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i)
0763     e->removeChild(l->item(i));
0764 #endif
0765 }
0766 
0767 bool Handle_t::hasChild(const XmlChar* tag_value) const {
0768   return node_first(m_node, tag_value) != 0;
0769 }
0770 
0771 /// Set the element's value
0772 void Handle_t::setValue(const XmlChar* text_value) const {
0773   _N(m_node)->setNodeValue(text_value);
0774 }
0775 
0776 /// Set the element's value
0777 void Handle_t::setValue(const std::string& text_value) const {
0778 #ifdef DD4HEP_USE_TINYXML
0779   _N(m_node)->setNodeValue(text_value.c_str());
0780 #else
0781   _N(m_node)->setNodeValue(Strng_t(text_value));
0782 #endif
0783 }
0784 
0785 /// Set the element's text
0786 void Handle_t::setText(const XmlChar* text_value) const {
0787 #ifdef DD4HEP_USE_TINYXML
0788   _N(m_node)->LinkEndChild(new TiXmlText(text_value));
0789 #else
0790   _N(m_node)->setTextContent(text_value);
0791 #endif
0792 }
0793 
0794 /// Set the element's text
0795 void Handle_t::setText(const std::string& text_value) const {
0796 #ifdef DD4HEP_USE_TINYXML
0797   _N(m_node)->LinkEndChild(new TiXmlText(text_value.c_str()));
0798 #else
0799   _N(m_node)->setTextContent(Strng_t(text_value));
0800 #endif
0801 }
0802 
0803 /// Remove all attributes of this element
0804 void Handle_t::removeAttrs() const {
0805 #ifdef DD4HEP_USE_TINYXML
0806   _E(m_node)->ClearAttributes();
0807 #else
0808   xercesc::DOMElement* e = _E(m_node);
0809   xercesc::DOMNamedNodeMap* l = e->getAttributes();
0810   for (XmlSize_t i = 0, n = l->getLength(); i < n; ++i) {
0811     xercesc::DOMAttr* a = (xercesc::DOMAttr*) l->item(i);
0812     e->removeAttributeNode(a);
0813   }
0814 #endif
0815 }
0816 
0817 /// Set attributes as in argument handle
0818 #ifdef DD4HEP_USE_TINYXML
0819 void Handle_t::setAttrs(Handle_t elt) const {
0820   removeAttrs();
0821   TiXmlElement* e = Xml(elt).e;
0822   for(TiXmlAttribute* a=e->FirstAttribute(); a; a=a->Next())
0823     e->SetAttribute(a->Name(),a->Value());
0824 }
0825 #else
0826 void Handle_t::setAttrs(Handle_t /* elt */) const {
0827   removeAttrs();
0828   xercesc::DOMElement* e = _E(m_node);
0829   xercesc::DOMNamedNodeMap* l = e->getAttributes();
0830   for (XmlSize_t i = 0, len = l->getLength(); i < len; ++i) {
0831     xercesc::DOMNode* n = l->item(i);
0832     if (n->getNodeType() == xercesc::DOMNode::ATTRIBUTE_NODE) {
0833       xercesc::DOMAttr* a = (xercesc::DOMAttr*) n;
0834       e->setAttribute(a->getName(), a->getValue());
0835     }
0836   }
0837 }
0838 #endif
0839 
0840 /// Access attribute pointer by the attribute's unicode name (throws exception if not present)
0841 Attribute Handle_t::attr_ptr(const XmlChar* t) const {
0842   Attribute a = attribute_node(m_node, t);
0843   if (0 != a)
0844     return a;
0845   std::string msg = "Handle_t::attr_ptr: ";
0846   if (m_node)
0847     msg += "Element [" + tag() + "] has no attribute of type '" + _toString(t) + "'";
0848   else
0849     msg += "Element [INVALID] has no attribute of type '" + _toString(t) + "'";
0850   throw std::runtime_error(msg);
0851 }
0852 
0853 /// Access attribute name (throws exception if not present)
0854 const XmlChar* Handle_t::attr_name(const Attribute a) const {
0855   if (a) {
0856     return Xml(a).a->getName();
0857   }
0858   throw std::runtime_error("Attempt to access invalid XML attribute object!");
0859 }
0860 
0861 /// Access attribute value by the attribute's unicode name (throws exception if not present)
0862 const XmlChar* Handle_t::attr_value(const XmlChar* attr_tag) const {
0863   return attribute_value(attr_ptr(attr_tag));
0864 }
0865 
0866 /// Access attribute value by the attribute  (throws exception if not present)
0867 const XmlChar* Handle_t::attr_value(const Attribute attr_val) const {
0868   return attribute_value(attr_val);
0869 }
0870 
0871 /// Access attribute value by the attribute's unicode name (no exception thrown if not present)
0872 const XmlChar* Handle_t::attr_value_nothrow(const XmlChar* attr_tag) const {
0873   Attribute a = attr_nothrow(attr_tag);
0874   return a ? attribute_value(a) : 0;
0875 }
0876 
0877 /// Generic attribute setter with integer value
0878 Attribute Handle_t::setAttr(const XmlChar* nam, int val) const {
0879   char txt[32];
0880   ::snprintf(txt, sizeof(txt), "%d", val);
0881   return setAttr(nam, Strng_t(txt));
0882 }
0883 
0884 /// Generic attribute setter with boolen value
0885 Attribute Handle_t::setAttr(const XmlChar* name, bool val) const {
0886   char txt[32];
0887   ::snprintf(txt, sizeof(txt), "%s", val ? "true" : "false");
0888   return setAttr(name, Strng_t(txt));
0889 }
0890 
0891 /// Generic attribute setter with floating point value
0892 Attribute Handle_t::setAttr(const XmlChar* name, float val) const {
0893   char txt[32];
0894   ::snprintf(txt, sizeof(txt), "%.8e", val);
0895   return setAttr(name, Strng_t(txt));
0896 }
0897 
0898 /// Generic attribute setter with double precision floating point value
0899 Attribute Handle_t::setAttr(const XmlChar* name, double val) const {
0900   char txt[32];
0901   ::snprintf(txt, sizeof(txt), "%.8e", val);
0902   return setAttr(name, Strng_t(txt));
0903 }
0904 
0905 /// Generic attribute setter with string value
0906 Attribute Handle_t::setAttr(const XmlChar* name, const std::string& val) const {
0907   return setAttr(name, Strng_t(val.c_str()));
0908 }
0909 
0910 #ifndef DD4HEP_USE_TINYXML
0911 Attribute Handle_t::setAttr(const XmlChar* name, const char* v) const {
0912   return setAttr(name, Strng_t(v));
0913 }
0914 #endif
0915 
0916 /// Generic attribute setter with XmlAttr value
0917 Attribute Handle_t::setAttr(const XmlChar* nam, const Attribute v) const {
0918   return v ? setAttr(nam, attribute_value(v)) : 0;
0919 }
0920 
0921 /// Generic attribute setter with unicode value
0922 Attribute Handle_t::setAttr(const XmlChar* nam, const XmlChar* val) const {
0923 #ifdef DD4HEP_USE_TINYXML
0924   TiXmlElement* e = Xml(m_node).e;
0925   e->SetAttribute(nam,val);
0926   return Attribute(e->AttributeNode(nam));
0927 #else
0928   xercesc::DOMElement* e = _E(m_node);
0929   xercesc::DOMAttr* a = e->getAttributeNode(nam);
0930   if (!a) {
0931     a = e->getOwnerDocument()->createAttribute(nam);
0932     e->setAttributeNode(a);
0933   }
0934   a->setValue(val);
0935   return Attribute(a);
0936 #endif
0937 }
0938 
0939 /// Add reference child as a new child node. The obj must have the "name" attribute!
0940 Handle_t Handle_t::setRef(const XmlChar* tag_value, const XmlChar* ref_name) {
0941   Element me(*this);
0942   Element ref(me.document(), tag_value);
0943   ref.setAttr(Unicode_ref, ref_name);
0944   me.append(ref);
0945   return ref;
0946 }
0947 
0948 /// Add reference child as a new child node. The obj must have the "name" attribute!
0949 Handle_t Handle_t::setRef(const XmlChar* tag_value, const std::string& ref_name) {
0950   return setRef(tag_value, Strng_t(ref_name).ptr());
0951 }
0952 
0953 /// Checksum (sub-)tree of a xml document/tree
0954 static unsigned int adler32(unsigned int adler, const XmlChar* xml_buff, size_t len) {
0955 #define DO1(buf,i)  {s1 +=(unsigned char)buf[i]; s2 += s1;}
0956 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
0957 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
0958 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
0959 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
0960 
0961   static const unsigned int BASE = 65521; /* largest prime smaller than 65536 */
0962   /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
0963   static const unsigned int NMAX = 5550;
0964   unsigned int s1 = adler & 0xffff;
0965   unsigned int s2 = (adler >> 16) & 0xffff;
0966   const char* buf = (const char*)xml_buff;
0967 
0968   if (buf == NULL)
0969     return 1;
0970 
0971   while (len > 0) {
0972     int k = len < NMAX ? (int) len : NMAX;
0973     len -= k;
0974     while (k >= 16) {
0975       DO16(buf);
0976       buf += 16;
0977       k -= 16;
0978     }
0979     if (k != 0)
0980       do {
0981         s1 += (unsigned char) *buf++;
0982         s2 += s1;
0983       } while (--k);
0984     s1 %= BASE;
0985     s2 %= BASE;
0986   }
0987   unsigned int result = (s2 << 16) | s1;
0988   return result;
0989 }
0990 
0991 /// Checksum (sub-)tree of a xml document/tree
0992 typedef unsigned int (fcn_t)(unsigned int, const XmlChar*, size_t);
0993 unsigned int Handle_t::checksum(unsigned int param, fcn_t fcn) const {
0994 #ifdef DD4HEP_USE_TINYXML
0995   typedef std::map<std::string, std::string> StringMap;
0996   TiXmlNode* n = Xml(m_node).n;
0997   if ( n ) {
0998     if ( 0 == fcn ) fcn = adler32;
0999     switch (n->Type()) {
1000     case TiXmlNode::ELEMENT: {
1001       std::map<std::string,std::string> m;
1002       TiXmlElement* e = n->ToElement();
1003       TiXmlAttribute* p=e->FirstAttribute();
1004       for(; p; p=p->Next()) m.emplace(p->Name(),p->Value());
1005       param = (*fcn)(param,e->Value(),::strlen(e->Value()));
1006       for(StringMap::const_iterator i=m.begin();i!=m.end();++i) {
1007         param = (*fcn)(param,(*i).first.c_str(),(*i).first.length());
1008         param = (*fcn)(param,(*i).second.c_str(),(*i).second.length());
1009       }
1010       break;
1011     }
1012     case TiXmlNode::TEXT:
1013       param = (*fcn)(param,n->ToText()->Value(),::strlen(n->ToText()->Value()));
1014       break;
1015     case TiXmlNode::UNKNOWN:
1016     case TiXmlNode::COMMENT:
1017     case TiXmlNode::DOCUMENT:
1018     case TiXmlNode::DECLARATION:
1019     default:
1020       break;
1021     }
1022     for(TiXmlNode* c=n->FirstChild(); c; c=c->NextSibling())
1023       param = Handle_t((XmlElement*)c->ToElement()).checksum(param,fcn);
1024   }
1025 #else
1026   if ( 0 == fcn ) fcn = adler32;
1027   if ( 0 == fcn )  {
1028   }
1029 #endif
1030   return param;
1031 }
1032 
1033 /// Create DOM element
1034 Handle_t Document::createElt(const XmlChar* tag_value) const {
1035 #ifdef DD4HEP_USE_TINYXML
1036   return _XE(new TiXmlElement(tag_value));
1037 #else
1038   return _XE(_D(m_doc)->createElement(tag_value));
1039 #endif
1040 }
1041 
1042 /// Access the ROOT eleemnt of the DOM document
1043 Handle_t Document::root() const {
1044   if (m_doc)
1045     return _XE(_D(m_doc)->getDocumentElement());
1046   throw std::runtime_error("Document::root: Invalid handle!");
1047 }
1048 
1049 /// Acces the document URI
1050 std::string Document::uri() const   {
1051   if (m_doc)   {
1052     Tag_t val(_D(m_doc)->getDocumentURI());
1053     return val;
1054   }
1055   throw std::runtime_error("Document::uri: Invalid handle!");
1056 }
1057 
1058 /// Assign new document. Old document is dropped.
1059 DocumentHolder& DocumentHolder::assign(DOC d)   {
1060   if (m_doc)   {
1061     printout(DEBUG,"DocumentHolder","+++ Release DOM document....");
1062 #ifdef DD4HEP_USE_TINYXML
1063     delete _D(m_doc);
1064 #else
1065     _D(m_doc)->release();
1066 #endif
1067   }
1068   m_doc = d;
1069   return *this;
1070 }
1071 
1072 /// Standard destructor - releases the document
1073 DocumentHolder::~DocumentHolder() {
1074   assign(0);
1075 }
1076 
1077 /// Constructor from DOM document entity
1078 Element::Element(const Document& doc, const XmlChar* type)
1079   : m_element(Xml(doc.createElt(type)).xe) {
1080 }
1081 
1082 /// Access the XmlElements parent
1083 Element::Elt_t Element::parentElement()  const   {
1084   Handle_t p = m_element.parent();
1085   if ( p && _N(p.ptr())->getNodeType() == ELEMENT_NODE_TYPE )  {
1086     return Elt_t(p);
1087   }
1088   return Elt_t(0);
1089 }
1090 
1091 /// Access the hosting document handle of this DOM element
1092 Document Element::document() const {
1093   return Document((XmlDocument*) (m_element ? _N(m_element)->getOwnerDocument() : 0));
1094 }
1095 
1096 /// Clone the DOM element tree
1097 Handle_t Element::clone(Handle_t h) const {
1098   if (m_element && h) {
1099     return h.clone(Document::DOC(document()));
1100   }
1101   throw std::runtime_error("Element::clone: Invalid element pointer -- unable to clone node!");
1102 }
1103 
1104 Attribute Element::getAttr(const XmlChar* name) const {
1105   return m_element ? attribute_node(m_element, name) : 0;
1106 }
1107 
1108 /// Set the reference attribute to the node (adds attribute ref="ref-name")
1109 Attribute Element::setRef(const XmlChar* tag_value, const XmlChar* ref_name) const {
1110   return setChild(tag_value).setAttr(Unicode_ref, ref_name);
1111 }
1112 
1113 /// Set the reference attribute to the node (adds attribute ref="ref-name")
1114 Attribute Element::setRef(const XmlChar* tag_value, const std::string& ref_name) const {
1115   return setRef(tag_value, Strng_t(ref_name).ptr());
1116 }
1117 
1118 /// Access the value of the reference attribute of the node (attribute ref="ref-name")
1119 const XmlChar* Element::getRef(const XmlChar* tag_value) const {
1120   return child(tag_value).attr < cpXmlChar > (Unicode_ref);
1121 }
1122 
1123 /// Add a new child to the DOM node
1124 Handle_t Element::addChild(const XmlChar* tag_value) const {
1125   Handle_t e = document().createElt(tag_value);
1126   m_element.append(e);
1127   return e;
1128 }
1129 
1130 /// Check if a child with the required tag exists - if not create it and add it to the current node
1131 Handle_t Element::setChild(const XmlChar* t) const {
1132   Elt_t e = m_element.child(t, false);
1133   return e ? Handle_t(e) : addChild(t);
1134 }
1135 
1136 #ifndef DD4HEP_USE_TINYXML
1137 /// Add comment node to the element
1138 void Element::addComment(const XmlChar* text_value) const {
1139   _N(m_element)->appendChild(_D(document().m_doc)->createComment(text_value));
1140 }
1141 #endif
1142 
1143 /// Add comment node to the element
1144 void Element::addComment(const char* text_value) const {
1145 #ifdef DD4HEP_USE_TINYXML
1146   _N(m_element)->appendChild(new TiXmlComment(text_value));
1147 #else
1148   _N(m_element)->appendChild(_D(document().m_doc)->createComment(Strng_t(text_value)));
1149 #endif
1150 }
1151 
1152 /// Add comment node to the element
1153 void Element::addComment(const std::string& text_value) const {
1154   addComment(text_value.c_str());
1155 }
1156 
1157 /// Initializing constructor to create a new XMLElement and add it to the document.
1158 RefElement::RefElement(const Document& doc, const XmlChar* typ, const XmlChar* nam)
1159   : Element(doc, typ) {
1160   m_name = nam ? setAttr(_U(name), nam) : 0;
1161 }
1162 
1163 /// Construction from existing object handle
1164 RefElement::RefElement(const Handle_t& e)
1165   : Element(e) {
1166   m_name = m_element ? getAttr(_U(name)) : 0;
1167 }
1168 
1169 /// Copy constructor
1170 RefElement::RefElement(const RefElement& e)
1171   : Element(e), m_name(e.m_name) {
1172 }
1173 
1174 /// Assignment operator
1175 RefElement& RefElement::operator=(const RefElement& e) {
1176   m_element = e.m_element;
1177   return *this;
1178 }
1179 
1180 const XmlChar* RefElement::name() const {
1181   if (0 == m_name)
1182     std::cout << "Error:tag=" << m_element.tag() << std::endl;
1183   return attribute_value(m_name);
1184 }
1185 
1186 const XmlChar* RefElement::refName() const {
1187   if (0 == m_name)
1188     std::cout << "Error:tag=" << m_element.tag() << std::endl;
1189   return attribute_value(m_name);
1190 }
1191 
1192 void RefElement::setName(const XmlChar* new_name) {
1193   setAttr(_U(name), new_name);
1194 }
1195 
1196 #ifndef DD4HEP_USE_TINYXML
1197 Collection_t::Collection_t(Handle_t element, const XmlChar* tag_value)
1198   : m_children(element, tag_value) {
1199   m_node = m_children.reset();
1200 }
1201 #endif
1202 
1203 Collection_t::Collection_t(Handle_t element, const char* tag_value)
1204   : m_children(element, Strng_t(tag_value)) {
1205   m_node = m_children.reset();
1206 }
1207 
1208 /// Constructor over XmlElements in a node list
1209 Collection_t::Collection_t(NodeList node_list)
1210   : m_children(node_list) {
1211   m_node = m_children.reset();
1212 }
1213 
1214 /// Reset the collection object to restart the iteration
1215 Collection_t& Collection_t::reset() {
1216   m_node = m_children.reset();
1217   return *this;
1218 }
1219 
1220 /// Access the collection size. Avoid this call -- sloooow!
1221 size_t Collection_t::size() const {
1222   return Handle_t(m_children.m_node).numChildren(m_children.m_tag, false);
1223 }
1224 
1225 /// Helper function to throw an exception
1226 void Collection_t::throw_loop_exception(const std::exception& e) const {
1227   if (m_node) {
1228     throw std::runtime_error(std::string(e.what()) + "\n" + "dd4hep: Error interpreting XML nodes of type <" + tag() + "/>");
1229   }
1230   throw std::runtime_error(std::string(e.what()) + "\n" + "dd4hep: Error interpreting collections XML nodes.");
1231 }
1232 
1233 void Collection_t::operator++() const {
1234   Elt_t e = this->parent();
1235   while (m_node) {
1236     m_node = m_children.next();
1237     if (m_node && _N(m_node)->getNodeType() == ELEMENT_NODE_TYPE) {
1238       if (this->parent() == e)
1239         return;
1240     }
1241   }
1242 }
1243 
1244 void Collection_t::operator--() const {
1245   Elt_t e = this->parent();
1246   while (m_node) {
1247     m_node = m_children.previous();
1248     if (m_node && _N(m_node)->getNodeType() == ELEMENT_NODE_TYPE) {
1249       if (this->parent() == e)
1250         return;
1251     }
1252   }
1253 }
1254 
1255 void Collection_t::operator++(int) const {
1256   ++(*this);
1257 }
1258 
1259 void Collection_t::operator--(int) const {
1260   --(*this);
1261 }
1262 
1263 Handle_t Document::clone(Handle_t source) const {
1264 #ifdef DD4HEP_USE_TINYXML
1265   return _XE(source.clone(0));
1266 #else
1267   return _XE(_D(m_doc)->importNode(_E(source.ptr()),true));
1268 #endif
1269 }
1270 
1271 #ifdef DD4HEP_USE_TINYXML
1272 //These files are located parallel to this one, we cannot use angle brackets for include
1273 #include "tinyxml_inl.h"
1274 #include "tinyxmlerror_inl.h"
1275 #include "tinyxmlparser_inl.h"
1276 #endif