File indexing completed on 2025-07-01 07:54:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <XML/Printout.h>
0016 #include <XML/UriReader.h>
0017 #include <XML/DocumentHandler.h>
0018
0019
0020 #include <memory>
0021 #include <iostream>
0022 #include <sys/types.h>
0023 #include <sys/stat.h>
0024 #ifndef _WIN32
0025 #include <libgen.h>
0026 #endif
0027 #include <TSystem.h>
0028
0029 using namespace dd4hep::xml;
0030
0031 namespace {
0032 std::string undressed_file_name(const std::string& fn) {
0033 if ( !fn.empty() ) {
0034 TString tfn(fn);
0035 gSystem->ExpandPathName(tfn);
0036 return std::string(tfn.Data());
0037 }
0038 return fn;
0039 }
0040 int s_minPrintLevel = dd4hep::INFO;
0041
0042 std::string _clean_fname(const std::string& filepath) {
0043
0044 std::string const& temp = getEnviron(filepath);
0045 std::string temp2 = undressed_file_name( temp.empty() ? filepath : temp );
0046 if ( strncmp(temp2.c_str(),"file:",5)==0 ) return temp2.substr(5);
0047 return temp2;
0048 }
0049
0050 }
0051
0052 #ifndef __TIXML__
0053 #include <xercesc/framework/LocalFileFormatTarget.hpp>
0054 #include <xercesc/framework/StdOutFormatTarget.hpp>
0055 #include <xercesc/framework/MemBufFormatTarget.hpp>
0056 #include <xercesc/framework/MemBufInputSource.hpp>
0057 #include <xercesc/sax/SAXParseException.hpp>
0058 #include <xercesc/sax/EntityResolver.hpp>
0059 #include <xercesc/sax/InputSource.hpp>
0060 #include <xercesc/parsers/XercesDOMParser.hpp>
0061 #include <xercesc/util/XMLEntityResolver.hpp>
0062 #include <xercesc/util/PlatformUtils.hpp>
0063 #include <xercesc/util/XercesDefs.hpp>
0064 #include <xercesc/util/XMLUni.hpp>
0065 #include <xercesc/util/XMLURL.hpp>
0066 #include <xercesc/util/XMLString.hpp>
0067 #include <xercesc/dom/DOM.hpp>
0068 #include <xercesc/sax/ErrorHandler.hpp>
0069
0070 using namespace xercesc;
0071
0072
0073 namespace dd4hep {
0074
0075
0076 namespace xml {
0077
0078
0079 class DocumentErrorHandler: public ErrorHandler, public DOMErrorHandler {
0080 public:
0081
0082 DocumentErrorHandler() {
0083 }
0084
0085 virtual ~DocumentErrorHandler() {
0086 printout(DEBUG,"DocumentErrorHandler","+++ Destructing the XercesC DOM-XML document error handler....");
0087 }
0088
0089 void resetErrors() {
0090 }
0091
0092 void warning(const SAXParseException& ) {
0093 }
0094
0095 void error(const SAXParseException& e);
0096
0097 void fatalError(const SAXParseException& e);
0098
0099 virtual bool handleError(const DOMError& domError);
0100 };
0101
0102
0103 bool DocumentErrorHandler::handleError(const DOMError& domError) {
0104 std::string err = "DOM UNKNOWN: ";
0105 switch (domError.getSeverity()) {
0106 case DOMError::DOM_SEVERITY_WARNING:
0107 err = "DOM WARNING: ";
0108 break;
0109 case DOMError::DOM_SEVERITY_ERROR:
0110 err = "DOM ERROR: ";
0111 break;
0112 case DOMError::DOM_SEVERITY_FATAL_ERROR:
0113 err = "DOM FATAL: ";
0114 break;
0115 default:
0116 return false;
0117 }
0118 printout(FATAL,"DocumentErrorHandler", "+++ %s %s: %s", err.c_str(),
0119 _toString(domError.getType()).c_str(),_toString(domError.getMessage()).c_str());
0120 DOMLocator* loc = domError.getLocation();
0121 if (loc) {
0122 printout(FATAL,"DocumentErrorHandler","+++ Location: Line:%d Column: %d",
0123 int(loc->getLineNumber()),int(loc->getColumnNumber()));
0124 }
0125 return false;
0126 }
0127
0128 void DocumentErrorHandler::error(const SAXParseException& e) {
0129 std::string m(_toString(e.getMessage()));
0130 if (m.find("The values for attribute 'name' must be names or name tokens") != std::string::npos
0131 || m.find("The values for attribute 'ID' must be names or name tokens") != std::string::npos
0132 || m.find("for attribute 'name' must be Name or Nmtoken") != std::string::npos
0133 || m.find("for attribute 'ID' must be Name or Nmtoken") != std::string::npos
0134 || m.find("for attribute 'name' is invalid Name or NMTOKEN value") != std::string::npos
0135 || m.find("for attribute 'ID' is invalid Name or NMTOKEN value") != std::string::npos)
0136 return;
0137 std::string sys(_toString(e.getSystemId()));
0138 printout(ERROR,"XercesC","+++ Error at file \"%s\", Line %d Column: %d Message:%s",
0139 sys.c_str(), int(e.getLineNumber()), int(e.getColumnNumber()), m.c_str());
0140 }
0141
0142 void DocumentErrorHandler::fatalError(const SAXParseException& e) {
0143 std::string m(_toString(e.getMessage()));
0144 std::string sys(_toString(e.getSystemId()));
0145 printout(FATAL,"XercesC","+++ FATAL Error at file \"%s\", Line %d Column: %d Message:%s",
0146 sys.c_str(), int(e.getLineNumber()), int(e.getColumnNumber()), m.c_str());
0147 }
0148
0149 namespace {
0150
0151
0152 class dd4hepDOMParser : public XercesDOMParser {
0153
0154 UriReader* m_reader;
0155
0156 DocumentErrorHandler m_errHandle_tr;
0157 class Resolver : public XMLEntityResolver {
0158 dd4hepDOMParser* parser;
0159 public:
0160 Resolver(dd4hepDOMParser* p) : parser(p) {}
0161 virtual ~Resolver() {}
0162 virtual InputSource *resolveEntity(XMLResourceIdentifier *id)
0163 { return parser->read_uri(id); }
0164 };
0165 Resolver m_resolver;
0166 public:
0167
0168 dd4hepDOMParser(UriReader* rdr) : XercesDOMParser(), m_reader(rdr), m_resolver(this) {
0169
0170 setErrorHandler(&m_errHandle_tr);
0171 setXMLEntityResolver(&m_resolver);
0172 }
0173
0174 virtual ~dd4hepDOMParser() {
0175
0176 }
0177
0178 InputSource *read_uri(XMLResourceIdentifier *id) {
0179 if ( m_reader ) {
0180 std::string buf, systemID(_toString(id->getSystemId()));
0181 if ( m_reader->load(systemID, buf) ) {
0182 const XMLByte* input = (const XMLByte*)XMLString::replicate(buf.c_str());
0183 #if 0
0184 std::string baseURI(_toString(id->getBaseURI()));
0185 std::string schema(_toString(id->getSchemaLocation()));
0186 std::string ns(_toString(id->getNameSpace()));
0187 if ( s_minPrintLevel <= INFO ) {
0188 printout(INFO,"XercesC","+++ Resolved URI: sysID:%s uri:%s ns:%s schema:%s",
0189 systemID.c_str(), baseURI.c_str(), ns.c_str(), schema.c_str());
0190 }
0191 #endif
0192 return new MemBufInputSource(input,buf.length(),systemID.c_str(),true);
0193 }
0194 }
0195 return 0;
0196 }
0197 };
0198
0199
0200 XercesDOMParser* make_parser(UriReader* reader=0) {
0201 XercesDOMParser* parser = new dd4hepDOMParser(reader);
0202 parser->setValidationScheme(XercesDOMParser::Val_Auto);
0203 parser->setValidationSchemaFullChecking(true);
0204 parser->setCreateEntityReferenceNodes(false);
0205 parser->setDoNamespaces(false);
0206 parser->setDoSchema(true);
0207
0208
0209
0210
0211
0212 return parser;
0213 }
0214 }
0215
0216
0217 void dumpTree(DOMNode* doc, std::ostream& os) {
0218 if ( doc ) {
0219 DOMImplementation *imp = DOMImplementationRegistry::getDOMImplementation(Strng_t("LS"));
0220 MemBufFormatTarget *tar = new MemBufFormatTarget();
0221 DOMLSOutput *out = imp->createLSOutput();
0222 DOMLSSerializer *wrt = imp->createLSSerializer();
0223 out->setByteStream(tar);
0224 wrt->getDomConfig()->setParameter(Strng_t("format-pretty-print"), true);
0225 wrt->write(doc, out);
0226 os << tar->getRawBuffer() << std::endl << std::flush;
0227 out->release();
0228 wrt->release();
0229 return;
0230 }
0231 printout(ERROR,"dumpTree","+++ Cannot dump invalid document.");
0232 }
0233
0234
0235 void dump_doc(DOMDocument* doc, std::ostream& os) {
0236 dumpTree(doc,os);
0237 }
0238
0239 void dump_tree(Handle_t elt, std::ostream& os) {
0240 dumpTree((DOMNode*)elt.ptr(),os);
0241 }
0242
0243 void dump_tree(Document doc, std::ostream& os) {
0244 dump_doc((DOMDocument*)doc.ptr(),os);
0245 }
0246 }
0247 }
0248
0249 #ifdef DD4HEP_NONE
0250
0251 std::string DocumentHandler::system_path(Handle_t base, const std::string& fn) {
0252 std::string path = system_path(base);
0253 std::string dir = ::dirname((char*)path.c_str());
0254 return dir+fn;
0255 }
0256 #else
0257
0258 #include <TUri.h>
0259 #include <TUrl.h>
0260 #endif
0261
0262
0263 std::string DocumentHandler::system_path(Handle_t base, const std::string& fn) {
0264 std::string path, dir = system_path(base);
0265 TUri uri_base(dir.c_str()), uri_rel(fn.c_str());
0266 TUrl url_base(dir.c_str());
0267 path = TUri::MergePaths(uri_rel,uri_base);
0268 TUri final(path.c_str());
0269 final.Normalise();
0270 path = url_base.GetProtocol()+std::string("://")+final.GetUri().Data();
0271 if ( path[path.length()-1]=='/' ) path = path.substr(0,path.length()-1);
0272 return path;
0273 }
0274
0275
0276 std::string DocumentHandler::system_path(Handle_t base) {
0277 DOMElement* elt = (DOMElement*)base.ptr();
0278 std::string path = _toString(elt->getBaseURI());
0279 if ( path[0] == '/' ) {
0280 std::string tmp = "file:"+path;
0281 return tmp;
0282 }
0283 return path;
0284 }
0285
0286
0287 Document DocumentHandler::load(Handle_t base, const XMLCh* fname, UriReader* reader) const {
0288 std::string path;
0289 DOMElement* elt = (DOMElement*)base.ptr();
0290 try {
0291 Document doc;
0292 Strng_t p = _toString(fname);
0293 path = _toString(fname);
0294
0295 try {
0296 XMLURL ref_url(elt->getBaseURI(), p);
0297 path = _toString(ref_url.getURLText());
0298 }
0299 catch(...) {
0300 }
0301 return load(path, reader);
0302 }
0303 catch(const std::exception& exc) {
0304 std::string b = _toString(elt->getBaseURI());
0305 std::string e = _toString(fname);
0306 printout(DEBUG,"DocumentHandler","+++ URI exception: %s -> %s [%s]",b.c_str(),e.c_str(),exc.what());
0307 }
0308 catch(...) {
0309 std::string b = _toString(elt->getBaseURI());
0310 std::string e = _toString(fname);
0311 printout(DEBUG,"DocumentHandler","+++ URI exception: %s -> %s",b.c_str(),e.c_str());
0312 }
0313 if ( reader ) {
0314 std::string buf, sys = system_path(base,fname);
0315 #if 0
0316 std::string buf, sys, dir = _toString(elt->getBaseURI());
0317 std::string fn = _toString(fname);
0318 dir = ::dirname((char*)dir.c_str());
0319 while( fn.substr(0,3) == "../" ) {
0320 dir = ::dirname((char*)dir.c_str());
0321 fn = fn.substr(3);
0322 }
0323 sys = dir + "/" + fn;
0324 #endif
0325 if ( reader->load(sys, buf) ) {
0326 #if 0
0327 Document doc = parse(buf.c_str(), buf.length(), sys.c_str(), reader);
0328 dumpTree(doc);
0329 return doc;
0330 #endif
0331 return parse(buf.c_str(), buf.length(), sys.c_str(), reader);
0332 }
0333 }
0334 return Document(0);
0335 }
0336
0337
0338 Document DocumentHandler::load(const std::string& fname, UriReader* reader) const {
0339 auto fname_clean = _clean_fname(fname);
0340 std::string path;
0341 printout(DEBUG,"DocumentHandler","+++ Loading document URI: %s",fname_clean.c_str());
0342 try {
0343 size_t idx = fname_clean.find(':');
0344 size_t idq = fname_clean.find('/');
0345 if ( idq == std::string::npos ) idq = 0;
0346 XMLURL xerurl = (const XMLCh*) Strng_t(idx==std::string::npos || idx>idq ? "file:"+fname_clean : fname_clean);
0347 std::string proto = _toString(xerurl.getProtocolName());
0348 path = _toString(xerurl.getPath());
0349 printout(DEBUG,"DocumentHandler","+++ protocol:%s path:%s",proto.c_str(), path.c_str());
0350 }
0351 catch(...) {
0352 }
0353 std::unique_ptr < XercesDOMParser > parser(make_parser(reader));
0354 try {
0355 if ( !path.empty() ) {
0356 parser->parse(path.c_str());
0357 if ( reader ) reader->parserLoaded(path);
0358 }
0359 else {
0360 if ( reader && reader->load(fname_clean, path) ) {
0361 MemBufInputSource src((const XMLByte*)path.c_str(), path.length(), fname.c_str(), false);
0362 parser->parse(src);
0363 return (XmlDocument*)parser->adoptDocument();
0364 }
0365 return (XmlDocument*)0;
0366 }
0367 }
0368 catch (const std::exception& e) {
0369 printout(ERROR,"DocumentHandler","+++ Exception(XercesC): parse(path):%s",e.what());
0370 try {
0371 parser->parse(fname.c_str());
0372 if ( reader ) reader->parserLoaded(path);
0373 }
0374 catch (const std::exception& ex) {
0375 printout(FATAL,"DocumentHandler","+++ Exception(XercesC): parse(URI):%s",ex.what());
0376 throw;
0377 }
0378 }
0379 printout(DEBUG,"DocumentHandler","+++ Document %s succesfully parsed with XercesC .....",path.c_str());
0380 return (XmlDocument*)parser->adoptDocument();
0381 }
0382
0383
0384 Document DocumentHandler::parse(const char* bytes, size_t length, const char* sys_id, UriReader* rdr) const {
0385 std::unique_ptr < XercesDOMParser > parser(make_parser(rdr));
0386 MemBufInputSource src((const XMLByte*)bytes, length, sys_id, false);
0387 parser->parse(src);
0388 DOMDocument* doc = parser->adoptDocument();
0389 doc->setXmlStandalone(true);
0390 doc->setStrictErrorChecking(true);
0391 return (XmlDocument*) doc;
0392 }
0393
0394
0395 int DocumentHandler::output(Document doc, const std::string& fname) const {
0396 XMLFormatTarget *tar = 0;
0397 DOMImplementation *imp = DOMImplementationRegistry::getDOMImplementation(Strng_t("LS"));
0398 DOMLSOutput *out = imp->createLSOutput();
0399 DOMLSSerializer *wrt = imp->createLSSerializer();
0400
0401 if (fname.empty())
0402 tar = new StdOutFormatTarget();
0403 else {
0404 std::string fn = undressed_file_name(fname);
0405 tar = new LocalFileFormatTarget(Strng_t(fn));
0406 }
0407 out->setByteStream(tar);
0408 wrt->getDomConfig()->setParameter(Strng_t("format-pretty-print"), true);
0409 wrt->write((xercesc::DOMDocument*) doc.ptr(), out);
0410 out->release();
0411 wrt->release();
0412 delete tar;
0413 return 1;
0414 }
0415
0416 #else
0417
0418 #include <XML/tinyxml.h>
0419
0420
0421 namespace dd4hep {
0422
0423 namespace xml {
0424
0425
0426 class DocumentErrorHandler {};
0427
0428 union Xml {
0429 Xml(void* ptr) : p(ptr) {}
0430 Xml(const void* ptr) : cp(ptr) {}
0431 void* p;
0432 const void* cp;
0433 TiXmlElement* e;
0434 XmlElement* xe;
0435 TiXmlAttribute* a;
0436 Attribute attr;
0437 TiXmlNode* n;
0438 TiXmlDocument* d;
0439 XmlDocument* xd;
0440 };
0441 }}
0442
0443
0444 std::string DocumentHandler::system_path(Handle_t base, const std::string& fname) {
0445 std::string fn, clean = _clean_fname(fname);
0446 struct stat st;
0447 Element elt(base);
0448
0449 if ( elt ) {
0450 std::string bn = Xml(elt.document()).d->Value();
0451 #ifdef _WIN32
0452 char drive[_MAX_DRIVE], dir[_MAX_DIR], file[_MAX_FNAME], ext[_MAX_EXT];
0453 ::_splitpath(bn.c_str(),drive,dir,file,ext);
0454 fn = drive;
0455 fn += ":";
0456 fn += dir;
0457 fn += "/";
0458 fn += clean;
0459 #else
0460 fn = ::dirname((char*)bn.c_str());
0461 #endif
0462 fn += "/";
0463 fn += _clean_fname(fname);
0464 }
0465 if ( ::stat(fn.c_str(),&st)==0 )
0466 return fn;
0467 else if ( ::stat(clean.c_str(),&st)==0 )
0468 return clean;
0469 return fname;
0470 }
0471
0472
0473 std::string DocumentHandler::system_path(Handle_t base) {
0474 std::string fn;
0475 Element elt(base);
0476
0477 if ( elt ) {
0478 fn = Xml(elt.document()).d->Value();
0479 }
0480 return undressed_file_name(fn);
0481 }
0482
0483
0484 Document DocumentHandler::load(const std::string& fname, UriReader* reader) const {
0485 std::string clean = _clean_fname(fname);
0486 if ( reader ) {
0487 printout(WARNING,"DocumentHandler","+++ Loading document URI: %s %s",
0488 fname.c_str(),"[URI Resolution is not supported by TiXML]");
0489 }
0490 else if ( s_minPrintLevel <= INFO ) {
0491 printout(INFO,"DocumentHandler","+++ Loading document URI: %s [Resolved:'%s']",
0492 fname.c_str(),clean.c_str());
0493 }
0494 TiXmlDocument* doc = new TiXmlDocument(clean.c_str());
0495 bool result = false;
0496 try {
0497 result = doc->LoadFile();
0498 if ( !result ) {
0499 if ( doc->Error() ) {
0500 printout(FATAL,"DocumentHandler","+++ Error (TinyXML) parsing XML document:%s [%s]",
0501 fname.c_str(), clean.c_str());
0502 printout(FATAL,"DocumentHandler","+++ Error (TinyXML) XML parsing error:%s",
0503 doc->ErrorDesc());
0504 printout(FATAL,"DocumentHandler","+++ Document:%s Location Line:%d Column:%d",
0505 doc->Value(), doc->ErrorRow(), doc->ErrorCol());
0506 except("dd4hep:XML","++ file:%s error:%s",clean.c_str(),doc->ErrorDesc());
0507 }
0508 except("dd4hep:XML","++ Unknown error (TinyXML) while parsing:%s",fname.c_str());
0509 }
0510 }
0511 catch(std::exception& e) {
0512 printout(ERROR,"DocumentHandler","+++ Exception (TinyXML): parse(path):%s",e.what());
0513 }
0514 if ( result ) {
0515 if ( s_minPrintLevel <= INFO ) {
0516 printout(INFO,"DocumentHandler","+++ Document %s succesfully parsed with TinyXML .....",
0517 fname.c_str());
0518 }
0519 return (XmlDocument*)doc;
0520 }
0521 delete doc;
0522 return 0;
0523 }
0524
0525
0526 Document DocumentHandler::load(Handle_t base, const XmlChar* fname, UriReader* reader) const {
0527 std::string path = system_path(base, fname);
0528 return load(path,reader);
0529 }
0530
0531
0532 Document DocumentHandler::parse(const char* bytes, size_t length, const char* , UriReader* reader) const {
0533 if ( reader ) {
0534 printout(WARNING,"DocumentHandler","+++ Parsing memory document %s",
0535 "[URI Resolution is not supported by TiXML]");
0536 }
0537 TiXmlDocument* doc = new TiXmlDocument();
0538 try {
0539 if ( bytes ) {
0540 size_t str_len = ::strlen(bytes);
0541 size_t len = length;
0542
0543 if ( str_len+1 != len || bytes[str_len] != 0 || ::isspace(bytes[str_len-1]) ) {
0544 std::unique_ptr<char[]> data(new char[len+1]);
0545 char* buff = data.get();
0546 try {
0547 ::memcpy(buff, bytes, len+1);
0548 buff[len] = 0;
0549 for(size_t i=len-1; i>0 && (buff[i]==0 || ::isspace(buff[i])); --i)
0550 buff[i] = 0;
0551 if ( 0 == doc->Parse(buff) ) {
0552 return (XmlDocument*)doc;
0553 }
0554 }
0555 catch(...) {
0556 }
0557 }
0558 if ( 0 == doc->Parse(bytes) ) {
0559 return (XmlDocument*)doc;
0560 }
0561 if ( doc->Error() ) {
0562 printout(FATAL,"DocumentHandler",
0563 "+++ Error (TinyXML) while parsing XML string [%s]",
0564 doc->ErrorDesc());
0565 printout(FATAL,"DocumentHandler",
0566 "+++ XML Document error: %s Location Line:%d Column:%d",
0567 doc->Value(), doc->ErrorRow(), doc->ErrorCol());
0568 throw std::runtime_error(std::string("dd4hep: ")+doc->ErrorDesc());
0569 }
0570 throw std::runtime_error("dd4hep: Unknown error while parsing XML document string with TiXml.");
0571 }
0572 throw std::runtime_error("dd4hep: FAILED to parse invalid document string [NULL] with TiXml.");
0573 }
0574 catch(std::exception& e) {
0575 printout(ERROR,"DocumentHandler","+++ Exception (TinyXML): parse(string):%s",e.what());
0576 }
0577 delete doc;
0578 return 0;
0579 }
0580
0581
0582 int DocumentHandler::output(Document doc, const std::string& fname) const {
0583 std::string fn = undressed_file_name(fname);
0584 FILE* file = fn.empty() ? stdout : ::fopen(fn.c_str(),"w");
0585 if ( !file ) {
0586 printout(ERROR,"DocumentHandler","+++ Failed to open output file: %s",fname.c_str());
0587 return 0;
0588 }
0589 TiXmlDocument* d = (TiXmlDocument*)doc.ptr();
0590 d->Print(file);
0591 if ( !fn.empty() ) ::fclose(file);
0592 return 1;
0593 }
0594
0595
0596 void dd4hep::xml::dump_tree(Handle_t elt, std::ostream& os) {
0597 TiXmlNode* node = (TiXmlNode*)elt.ptr();
0598 TiXmlPrinter printer;
0599 printer.SetStreamPrinting();
0600 node->Accept( &printer );
0601 os << printer.Str();
0602 }
0603
0604
0605 void dd4hep::xml::dump_tree(Document doc, std::ostream& os) {
0606 TiXmlDocument* node = (TiXmlDocument*)doc.ptr();
0607 TiXmlPrinter printer;
0608 printer.SetStreamPrinting();
0609 node->Accept( &printer );
0610 os << printer.Str();
0611 }
0612 #endif
0613
0614
0615
0616 DocumentHandler::DocumentHandler() {}
0617
0618
0619 DocumentHandler::~DocumentHandler() {}
0620
0621
0622 int DocumentHandler::setMinimumPrintLevel(int level) {
0623 int tmp = s_minPrintLevel;
0624 s_minPrintLevel = level;
0625 return tmp;
0626 }
0627
0628
0629 std::string DocumentHandler::defaultComment() {
0630 const char comment[] = "\n"
0631 " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
0632 " ++++ dd4hep generated alignment file using the ++++\n"
0633 " ++++ dd4hep Detector description XML generator. ++++\n"
0634 " ++++ ++++\n"
0635 " ++++ Parser:"
0636 XML_IMPLEMENTATION_TYPE
0637 " ++++\n"
0638 " ++++ ++++\n"
0639 " ++++ M.Frank CERN/LHCb ++++\n"
0640 " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n ";
0641 return comment;
0642 }
0643
0644
0645 Document DocumentHandler::load(const std::string& fname) const {
0646 return load(fname, 0);
0647 }
0648
0649
0650 Document DocumentHandler::load(Handle_t base, const XmlChar* fname) const {
0651 return load(base, fname, 0);
0652 }
0653
0654
0655 Document DocumentHandler::parse(const char* bytes, size_t length) const {
0656 return parse(bytes, length, "xml-memory-buffer", 0);
0657 }
0658
0659
0660 std::string DocumentHandler::system_path(Handle_t base, const XmlChar* fname) {
0661 std::string fn = _toString(fname);
0662 return system_path(base, fn);
0663 }
0664
0665
0666 std::string DocumentHandler::system_directory(Handle_t base, const XmlChar* fname) {
0667 std::string path = system_path(base,fname);
0668 std::string dir = ::dirname((char*)path.c_str());
0669 return dir;
0670 }
0671
0672
0673 std::string DocumentHandler::system_directory(Handle_t base) {
0674 std::string path = system_path(base);
0675 std::string dir = ::dirname((char*)path.c_str());
0676 return dir;
0677 }
0678
0679
0680 Document DocumentHandler::create(const char* tag, const char* comment) const {
0681 std::string top(tag);
0682 std::string empty = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
0683 empty += "<" + top + "/>\0\0";
0684 Document doc = parse(empty.c_str(), empty.length() + 1);
0685 if (comment) {
0686 Element top_elt = doc.root();
0687 top_elt.addComment(comment);
0688 }
0689 return doc;
0690 }
0691
0692
0693 Document DocumentHandler::create(const std::string& tag, const std::string& comment) const {
0694 return create(tag.c_str(), comment.c_str());
0695 }
0696
0697
0698 void dd4hep::xml::dump_tree(Handle_t elt) {
0699 dump_tree(elt,std::cout);
0700 }
0701
0702
0703 void dd4hep::xml::dump_tree(Document doc) {
0704 dump_tree(doc,std::cout);
0705 }