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