/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Calibration/xmlBase/xmlBase-00-00-03/src/Dom.cxx

Go to the documentation of this file.
00001 // $Header: /bes/bes/BossCvs/Calibration/xmlBase/src/Dom.cxx,v 1.2 2014/04/18 02:24:47 maqm Exp $
00002 // Author:  J. Bogart
00003 //
00004 // Implementation of xmlBase::Dom, a convenient place to put static
00005 // utilities which enhance DOM api.
00006 
00007 #include "xmlBase/Dom.h"
00008 #include <xercesc/dom/DOMElement.hpp>
00009 #include <xercesc/dom/DOMNodeList.hpp>
00010 #include <xercesc/dom/DOMCharacterData.hpp>
00011 #include <xercesc/dom/DOMNamedNodeMap.hpp>
00012 #include <xercesc/dom/DOMDocument.hpp>
00013 #include <xercesc/dom/DOMException.hpp>
00014 #include <xercesc/dom/DOMTreeWalker.hpp>
00015 #include <xercesc/util/TransService.hpp>
00016 #include <xercesc/util/XMLString.hpp>
00017 #include <xercesc/util/PlatformUtils.hpp>
00018 
00019 #include "facilities/Util.h"
00020 //#ifdef DEFECT_NO_STRINGSTREAM
00021 //#include <strstream>
00022 //#else
00023 #include <sstream>
00024 //#endif
00025 
00026 
00027 #include <string>
00028 #include <cstring>
00029 #include <cassert>
00030 
00031 namespace {
00032   XERCES_CPP_NAMESPACE_USE
00033 
00034   DOMTreeWalker* makeWalker(const DOMNode* node) {
00035     if (!node) return 0;
00036     DOMDocument* doc = node->getOwnerDocument();
00037     unsigned long whatToShow = DOMNodeFilter::SHOW_ELEMENT;
00038 
00039     bool expand = true;
00040     DOMNode* casted = const_cast<DOMNode*>(node);
00041     // Show only elements;  Expand entity references
00042     DOMTreeWalker* walk = doc->createTreeWalker(casted, whatToShow, 0, expand);
00043     return walk;
00044   }
00045 }
00046 
00047   
00048 namespace xmlBase {
00049   XERCES_CPP_NAMESPACE_USE
00050 
00051   XMLLCPTranscoder*  Dom::transcoder = 0;
00052   char*              Dom::transBuf = 0;
00053 
00054   unsigned int       Dom::transBufSize = 1000;
00055   XMLCh*             Dom::xmlchBuf = 0;
00056 
00057   unsigned int       Dom::xmlchBufSize = 200;
00058   XMLCh*             Dom::xmlchStar = 0;
00059 
00060   DOMElement* Dom::findFirstChildByName(const DOMElement* parent, 
00061                                         const char* const name) {
00062     
00063     if (!xmlchStar) xmlchStar = XMLString::transcode("*");    
00064     if (!(parent)) {
00065       throw NullNode("from xmlBase::Dom::findFirstChildByName. Null parent arg.");
00066     }
00067 
00068     XMLCh* xmlchName = XMLString::transcode(name);
00069 
00070     DOMTreeWalker* walk = makeWalker(parent);
00071     DOMElement* child = static_cast<DOMElement*>(walk->firstChild());
00072     if (XMLString::equals(xmlchName, xmlchStar)) return child;
00073 
00074     if (!child) return 0;
00075     // otherwise cycle through children, looking for first with right tag name
00076     while (! XMLString::equals(child->getNodeName(), xmlchName)) {
00077       child = static_cast<DOMElement*>(walk->nextSibling());
00078       if (!child) return 0;
00079     }
00080 
00081 
00082     XMLString::release(&xmlchName);
00083 
00084     walk->release();
00085     return child;
00086   }
00087 
00088   DOMElement* Dom::findFirstChildByName(const DOMElement* parent, 
00089                                         const std::string name) {
00090     return findFirstChildByName(parent, name.c_str());
00091   }
00092 
00093 
00094   // Leave this alone for now.  Entities are not likely to cause
00095   // trouble here.
00096   DOMElement* Dom::getSiblingElement(const DOMNode* child) {
00097     if (!child) {
00098       throw NullNode("from xmlBase::Dom::getSiblingElement. Null argument");
00099     }
00100 
00101     DOMNode* sib = child->getNextSibling();
00102 
00103     while (sib) {
00104       if (sib->getNodeType() == DOMNode::ELEMENT_NODE) {
00105         DOMElement* eltSib = static_cast<DOMElement*> (sib);
00106 
00107         return eltSib;
00108       }
00109       sib = sib->getNextSibling();
00110     }
00111 
00112     return 0;
00113   }
00114 
00115   DOMElement* Dom::getFirstChildElement(const DOMNode* parent) {
00116     const DOMElement* elt = static_cast<const DOMElement*>(parent);
00117     return findFirstChildByName(elt, "*");
00118   }
00119 
00120   DOMElement* Dom::getElementById(const DOMDocument* doc, 
00121                                   const std::string& id) {
00122     XMLCh* idChars = XMLString::transcode(id.c_str());
00123     DOMElement* elt = doc->getElementById(idChars);
00124     XMLString::release(&idChars);
00125     return elt;
00126   }
00127 
00128   std::string Dom::getNodeName(const DOMNode* node) {
00129     if (!node) {
00130       throw NullNode("Null node argument supplied to xmlBase::Dom::getNodeName");
00131     }
00132     const XMLCh* name = node->getNodeName();
00133     if (!name) return std::string("");
00134 
00135     char* chrName = XMLString::transcode(name);
00136 
00137     std::string strName = std::string(chrName);
00138     XMLString::release(&chrName);
00139     return strName;
00140   }
00141 
00142   std::string Dom::getTagName(const DOMElement* elt) {
00143     return Dom::getNodeName(elt);
00144   }
00145 
00146   bool Dom::checkTagName(const DOMElement* element, 
00147                          const std::string& tagName) {
00148    if (!element) {
00149      throw NullNode("Null dom element argument to xmlBase::Dom::checkTagName");
00150    }
00151    if (tagName == std::string("*")) return true;
00152    XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());
00153    bool ret = XMLString::equals(xmlchTagName, element->getTagName());
00154    XMLString::release(&xmlchTagName);
00155    return ret;
00156   }
00157    
00158 
00159 
00160   void Dom::getChildrenByTagName(const DOMElement* parent, 
00161                                  const std::string& tagName,
00162                                  std::vector<DOMElement*>& children,
00163                                  bool clear) {
00164     if (!parent) {
00165       throw NullNode("from xmlBase::Dom::getChildrenByTagName. Null parent arg");
00166     }
00167     if (clear) children.clear();
00168     DOMElement* child = getFirstChildElement(parent);
00169     while (child != 0) {
00170       if (checkTagName(child, tagName)) {
00171         children.push_back(child);
00172       }
00173       child = getSiblingElement(child);
00174     }
00175   }
00176 
00177 
00178   void Dom::getDescendantsByTagName(const DOMElement* parent, 
00179                                     const std::string& tagName,
00180                                     std::vector<DOMElement*>& children,
00181                                     bool clear) {
00182     if (parent == 0) {
00183       throw NullNode("from xmlBase::Dom::getChildrenByTagName. Null parent arg");
00184     }
00185     if (clear) children.clear();
00186     XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());;
00187     DOMNodeList* list = 
00188       parent->getElementsByTagName(xmlchTagName);
00189     XMLString::release(&xmlchTagName);
00190     unsigned int nItem = list->getLength();
00191     for (unsigned int iItem = 0; iItem < nItem; iItem++) {
00192       children.push_back(static_cast<DOMElement *>(list->item(iItem)));
00193     }
00194   }
00195 
00196   void Dom::getAttributeNodeMap(const DOMNode* node,
00197                                 std::map<std::string, DOMNode*>& atts,
00198                                 bool clear) {
00199 
00200     if (clear) atts.clear();
00201     DOMNamedNodeMap* nodeMap = node->getAttributes();
00202     unsigned int nAtts = nodeMap->getLength();
00203 
00204     for (unsigned iAtt = 0; iAtt < nAtts; iAtt++) {
00205       DOMNode* attNode = nodeMap->item(iAtt);
00206       atts[xmlBase::Dom::getNodeName(attNode)] = attNode;
00207     }
00208   }
00209 
00210   bool Dom::hasAttribute(const DOMNode* node, const char* attName) {
00211     bool ret = false;
00212     if (node == 0) return ret;
00213     if (node->getNodeType() != DOMNode::ELEMENT_NODE ) return ret;
00214 
00215     const DOMElement* elt = static_cast<const DOMElement*>(node);
00216     XMLCh* xmlchAttName = XMLString::transcode(attName);
00217     ret = (elt->getAttributeNode(xmlchAttName) != 0);
00218     XMLString::release(&xmlchAttName);
00219     return ret;
00220   }
00221 
00222   std::string   Dom::getAttribute(const DOMElement* elt, const char* attName) {
00223     if (elt == 0) {
00224       throw NullNode("from xmlBase::Dom::getAttribute. Null argument");
00225     }
00226 
00227     XMLCh* xmlchAttName = XMLString::transcode(attName);
00228     const XMLCh*  attValue = elt->getAttribute(xmlchAttName);
00229     XMLString::release(&xmlchAttName);
00230 
00231     if (attValue == 0) return std::string("");
00232 
00233     char* chrAttValue = XMLString::transcode(attValue);
00234     std::string strValue = std::string(chrAttValue);
00235     XMLString::release(&chrAttValue);
00236     return strValue;
00237   }
00238 
00239 
00240   std::string   Dom::getAttribute(const DOMElement* elt, 
00241                                   std::string attName) {
00242 
00243     return getAttribute(elt, attName.c_str());
00244   }
00245  
00246   std::string  Dom::getAttribute(const DOMNode* elt, const char* attName) {
00247     if (elt == 0) {
00248       throw NullNode("from xmlBase::Dom::getAttribute. Null argument");
00249     }
00250 
00251     if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
00252       throw NullNode("from xmlBase::Dom::getAttribute. Non-element argument");
00253     }
00254     return getAttribute(static_cast<const DOMElement*>(elt), attName);
00255   }
00256 
00257   std::string  Dom::getAttribute(const DOMNode* elt, 
00258                             std::string attName) {
00259     return getAttribute(elt, attName.c_str());
00260   }
00261 
00262 
00263   double Dom::getDoubleAttribute(const DOMNode* elt, std::string attName) {
00264     std::string stringValue = getAttribute(elt, attName);
00265     
00266     if (stringValue == std::string("") ) {
00267       throw
00268         NullNode("from xmlBase::Dom::getDoubleAttribute.  non-existent attribute");
00269     }
00270     try {
00271       return facilities::Util::stringToDouble(stringValue);
00272     }
00273     catch (facilities::WrongType ex) {
00274       std::cerr << ex.getMsg();
00275       throw WrongAttributeType("from xmlBase::Dom::getDoubleAttribute");
00276     }
00277   }
00278 
00279   unsigned Dom::getDoublesAttribute(const DOMNode* elt, std::string attName,
00280                                 std::vector<double>& values, bool clear) {
00281     unsigned nVals = 0;
00282     std::vector<std::string> tokens;
00283     if (clear) values.clear();
00284     std::string stringValue = getAttribute(elt, attName);
00285     if (stringValue.size() == 0) return nVals;
00286 
00287     facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
00288 
00289     try {
00290       unsigned nToken = tokens.size();
00291       for (unsigned iToken = 0;  iToken < nToken; iToken++) {
00292         values.push_back(facilities::Util::stringToDouble(tokens[iToken]));
00293         nVals++;
00294       }
00295     }
00296     catch (facilities::WrongType ex) {
00297       std::cerr << ex.getMsg();
00298       throw WrongAttributeType("from xmlBase::Dom::getDoublesAttribute");
00299     }
00300     return nVals;
00301   }
00302   unsigned Dom::getFloatsAttribute(const DOMNode* elt, std::string attName,
00303                                    std::vector<float>& values, bool clear) {
00304     unsigned nVals = 0;
00305     std::vector<std::string> tokens;
00306     if (clear) values.clear();
00307     std::string stringValue = getAttribute(elt, attName);
00308     if (stringValue.size() == 0) return nVals;
00309 
00310     facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
00311 
00312     try {
00313       unsigned nToken = tokens.size();
00314       for (unsigned iToken = 0;  iToken < nToken; iToken++) {
00315         values.push_back(facilities::Util::stringToDouble(tokens[iToken]));
00316         nVals++;
00317       }
00318     }
00319     catch (facilities::WrongType ex) {
00320       std::cerr << ex.getMsg();
00321       throw WrongAttributeType("from xmlBase::Dom::getDoublesAttribute");
00322     }
00323     return nVals;
00324   }
00325 
00326   int Dom::getIntAttribute(const DOMNode* elt, std::string attName) {
00327     std::string stringValue = getAttribute(elt, attName);
00328     
00329     if (stringValue == std::string("") ) {
00330       throw
00331         NullNode("from xmlBase::Dom::getIntAttribute.  non-existent attribute");
00332     }
00333     try {
00334       return facilities::Util::stringToInt(stringValue);
00335     }
00336     catch (facilities::WrongType ex) {
00337       std::cerr << ex.getMsg();
00338       throw WrongAttributeType("from xmlBase::Dom::getIntAttribute");
00339     }
00340   }
00341 
00342   unsigned Dom::getIntsAttribute(const DOMNode* elt, std::string attName,
00343                                  std::vector<int>& values, bool clear) {
00344     unsigned nVals = 0;
00345     std::vector<std::string> tokens;
00346     if (clear) values.clear();
00347     std::string stringValue = getAttribute(elt, attName);
00348     if (stringValue.size() == 0) return nVals;
00349 
00350     facilities::Util::stringTokenize(stringValue, std::string(" "), tokens);
00351 
00352     try {
00353       unsigned nToken = tokens.size();
00354       for (unsigned iToken = 0;  iToken < nToken; iToken++) {
00355         values.push_back(facilities::Util::stringToInt(tokens[iToken]));
00356         nVals++;
00357       }
00358     }
00359     catch (facilities::WrongType ex) {
00360       std::cerr << ex.getMsg();
00361       throw WrongAttributeType("from xmlBase::Dom::getIntsAttribute");
00362     }
00363     return nVals;
00364   }
00365 
00366   std::string Dom::getText(const DOMNode* textNode) {
00367     short int nType = textNode->getNodeType();
00368 
00369     if ( (nType != DOMNode::TEXT_NODE) &&
00370          (nType != DOMNode::COMMENT_NODE) &&
00371          (nType != DOMNode::CDATA_SECTION_NODE))
00372     {
00373       throw WrongNodeType("from xmlBase::Dom::getText, argument not text node");
00374     }
00375     const XMLCh* t = textNode->getNodeValue();
00376     if (t == 0 ) return std::string("");
00377     char* chrText = XMLString::transcode(t);
00378     std::string text = std::string(chrText);
00379     XMLString::release(&chrText);
00380 
00381     return text;
00382   }
00383 
00384 
00385   std::string Dom::getTextContent(const DOMElement* elt) {
00386     if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
00387       throw WrongNodeType("from xmlBase::Dom::getTextContent, argument not element node");
00388     }
00389     return (getText(elt->getFirstChild()));
00390   }
00391 
00392   void  Dom::addAttribute(DOMElement* elt, std::string name, 
00393                           double value) {
00394     if (elt == 0) {
00395       throw NullNode("from xmlBase::Dom::addAttribute.  null argument");
00396     }
00397 
00398     //#ifdef DEFECT_NO_STRINGSTREAM
00399     //    std::strstream s;
00400     //    s << value << '\0';
00401     //#else
00402     std::ostringstream s;
00403     s << value;
00404     //#endif
00405 
00406     std::string str = s.str();
00407     XMLCh* xmlchValue = XMLString::transcode(str.c_str());
00408     XMLCh* xmlchName = XMLString::transcode(name.c_str());
00409 
00410     try {
00411       elt->setAttribute(xmlchName, xmlchValue);
00412     }
00413     catch (DOMException ex) {
00414       char* msg = XMLString::transcode(ex.msg);
00415       std::cerr << "DOMException in xmlBase::Dom::addAttribute(double)" << std::endl;
00416       std::cerr << "Msg: " << std::string(msg) 
00417                 << "Code: " << ex.code << std::endl;
00418       XMLString::release(&msg);
00419       throw ex;
00420     }
00421     XMLString::release(&xmlchName);
00422     XMLString::release(&xmlchValue);
00423   }
00424 
00425 
00426   void  Dom::addAttribute(DOMElement* elt, std::string name, 
00427                                  int value) {
00428     if (elt == 0) {
00429       throw NullNode("from xmlBase::Dom::addAttribute.  Null argument");
00430     }
00431 
00432 
00433     //#ifdef DEFECT_NO_STRINGSTREAM
00434     //    std::strstream s;
00435     //    s << value << '\0';
00436     //#else
00437     std::ostringstream s;
00438     s << value;
00439     //#endif
00440 
00441     std::string str = s.str();
00442 
00443     XMLCh* xmlchValue = XMLString::transcode(str.c_str());
00444     XMLCh* xmlchName = XMLString::transcode(name.c_str());
00445 
00446     try {
00447       elt->setAttribute(xmlchName, xmlchValue);
00448     }
00449     catch (DOMException ex) {
00450       char* msg = XMLString::transcode(ex.msg);
00451       std::cerr << "DOMException in xmlBase::Dom::addAttribute(int)" 
00452                 << std::endl;
00453       std::cerr << "Msg: " << std::string(msg) 
00454                 << "Code: " << ex.code << std::endl;
00455       XMLString::release(&msg);
00456       throw ex;
00457     }
00458 
00459     XMLString::release(&xmlchName);
00460     XMLString::release(&xmlchValue);
00461 
00462   }
00463 
00464   void  Dom::addAttribute(DOMElement* elt, std::string name, 
00465                                  unsigned int value) {
00466     if (elt == 0) {
00467       throw NullNode("from xmlBase::Dom::addAttribute.  Null argument");
00468     }
00469 
00470     //#ifdef DEFECT_NO_STRINGSTREAM
00471     //    std::strstream s;
00472     //    s << value << '\0';
00473     //#else
00474     std::ostringstream s;
00475     s << value;
00476     //#endif
00477 
00478     std::string str = s.str();
00479 
00480     XMLCh* xmlchValue = XMLString::transcode(str.c_str());
00481     XMLCh* xmlchName = XMLString::transcode(name.c_str());
00482 
00483     try {
00484       elt->setAttribute(xmlchName, xmlchValue);
00485     }
00486     catch (DOMException ex) {
00487       char* msg = XMLString::transcode(ex.msg);
00488       std::cerr << "DOMException in xmlBase::Dom::addAttribute(unsigned int)" 
00489                 << std::endl;
00490       std::cerr << "Msg: " << std::string(msg) 
00491                 << "Code: " << ex.code << std::endl;
00492       XMLString::release(&msg);
00493       throw ex;
00494     }
00495     XMLString::release(&xmlchName);
00496     XMLString::release(&xmlchValue);
00497 
00498   }
00499 
00500   void  Dom::addAttribute(DOMElement* elt, std::string name, 
00501                                  const char* value) {
00502 
00503     if (elt == 0) {
00504       throw NullNode("from xmlBase::Dom::addAttribute.  Null argument");
00505     }
00506 
00507     XMLCh* xmlchValue = XMLString::transcode(value);
00508     XMLCh* xmlchName = XMLString::transcode(name.c_str());
00509 
00510     try {
00511       elt->setAttribute(xmlchName, xmlchValue);
00512     }
00513     catch (DOMException ex) {
00514       char* msg = XMLString::transcode(ex.msg);
00515       std::cerr << "DOMException in xmlBase::Dom::addAttribute(char*)" 
00516                 << std::endl;
00517       std::cerr << "Msg: " << std::string(msg) << "Code: " 
00518                 << ex.code << std::endl;
00519       std::cerr.flush();
00520       XMLString::release(&msg);
00521       throw ex;
00522     }
00523 
00524     XMLString::release(&xmlchName);
00525     XMLString::release(&xmlchValue);
00526 
00527   }
00528 
00529   void  Dom::addAttribute(DOMElement* elt, std::string name, 
00530                                  std::string value) {
00531 
00532     if (elt == 0)
00533       throw NullNode("from xmlBase::Dom::addAttribute. Null argument");
00534 
00535     addAttribute(elt, name, value.c_str());
00536   }
00537 
00538   /* 
00539       Serialize a node (and any children) to the specified ostream.
00540       prefix is for now ignored, but see note following.
00541  
00542       The only node types which actually do get written are
00543            element (and its attributes and children)
00544            text
00545            comment
00546 
00547       NB:  For this first pass, printElement outputs all the
00548            supported node types just as they appeared in the
00549            serialization before parsing *if* the parse was
00550            non-validating.  If it *was* validating (or if
00551            the DOM representation was built programmatically
00552            rather than by parsing a file) then ignorable 
00553            white space will have been thrown away (in the
00554            validated case) or there won't have been any to
00555            begin with (programmatically-built case)
00556            so the printed version will be a horrific single
00557            line except that line breaks appearing within
00558            comments or text nodes will be preserved.
00559 
00560            Ideally would like to be able to query the DOM
00561            or have an argument passed in to tell us whether
00562            ignorable white space has been thrown away, in which
00563            case we should attempt to pretty print by putting
00564            newlines in in reasonable places and keeping track
00565            of a sensible indentation level.
00566 
00567            For now, make two different functions.  See 
00568            prettyPrintElement below.
00569   */
00570   void Dom::printElement(DOMNode* node, std::ostream& out) {
00571 
00572     if (node == 0) {
00573       throw NullNode("from xmlBase::Dom::printElement. Null argument");
00574     }
00575 
00576     switch(node->getNodeType()) {
00577     case DOMNode::ELEMENT_NODE:
00578       {
00579         // output start tag
00580         {
00581           std::string tagName = getNodeName(node);
00582           out << '<' << tagName;
00583         }
00584         // ...with attributes  
00585 
00586         typedef std::map<std::string, DOMNode*> AttMap;
00587         AttMap atts;
00588         AttMap::const_iterator it;
00589         getAttributeNodeMap(node, atts);
00590 
00591         for (it = atts.begin();
00592              it != atts.end(); it++) {
00593           std::string attName = (*it).first;
00594           out << ' ' << attName << '=';
00595           out << '"' << getAttribute(node,attName) << '"';
00596         }
00597 
00598         // iterate through children
00599         DOMNode* child = node->getFirstChild();
00600         if (child != 0) {  // there are children
00601           out << '>';
00602           while (child != 0) {
00603             Dom::printElement(child, out);
00604             child = child->getNextSibling();
00605           }
00606           // output end tag, long form
00607           {
00608             std::string endName = getNodeName(node);
00609             out << "</" << endName << ">";
00610           }
00611         }
00612         else {  // no children; use short form for the empty tag
00613           out << " />";
00614         } 
00615       }
00616       break;
00617     case DOMNode::TEXT_NODE:
00618       // just put it out as is
00619       {
00620         out << getText(node);
00621       }
00622       break;
00623 
00624     case DOMNode::CDATA_SECTION_NODE:
00625       {
00626         out << "<![CDATA[" << getText(node) << "]]>";
00627       }
00628       break;
00629       
00630 
00631     case DOMNode::COMMENT_NODE :
00632       // glast.prs doesn't have any comments (but should!)
00633       {
00634         out << "<!-- " << getText(node) << "-->";
00635       }
00636       break;
00637     default:
00638       // ignore anything else
00639       break;
00640     }
00641   }
00642 
00643   // Assume we need to do the indenting and line breaks
00644   void Dom::prettyPrintElement(DOMNode* node, std::ostream& out,
00645                                std::string prefix) {
00646     
00647 
00648     if (node == 0) {
00649       throw NullNode("from xmlBase::Dom::prettyPrintElement. Null argument");
00650     }
00651 
00652     out << prefix;
00653     switch(node->getNodeType()) {
00654 
00655     case DOMNode::ELEMENT_NODE:
00656       {
00657         // output start tag
00658         std::string tagName = getNodeName(node);
00659         out << '<' << tagName;
00660 
00661         // ...with attributes
00662         typedef std::map<std::string, DOMNode*> AttMap;
00663         AttMap atts;
00664         AttMap::const_iterator it;
00665 
00666         getAttributeNodeMap(node, atts);
00667 
00668         for (it = atts.begin();
00669              it != atts.end(); it++) {
00670           std::string attName = (*it).first;
00671           out << ' ' << attName << '=';
00672           out << '"' << getAttribute(node,attName) << '"';
00673         }
00674 
00675         // iterate through children
00676         DOMNode* child = node->getFirstChild();
00677         if (child != 0) {  // there are children
00678           out << '>' << std::endl;
00679           while (child != 0) {
00680             // new indent level
00681             Dom::prettyPrintElement(child, out, prefix + "  ");
00682             child = child->getNextSibling();
00683           }
00684           // output end tag, long form
00685           {
00686             std::string endName = getNodeName(node);
00687             out << prefix << "</" << endName << ">" << std::endl;
00688           }
00689         }
00690         else {  // no children; use short form for the empty tag
00691           out << " />" << std::endl;
00692         } 
00693       }
00694       break;
00695     case DOMNode::TEXT_NODE:
00696       // just put it out as is
00697       // Note this won't indent correctly if the text node
00698       // contains multiple lines.
00699       // Similarly, it's too much work to avoid sometimes putting out
00700       // an "extra" blank line in the vicinity of text.
00701       // Current code puts the extra <cr> before
00702       // the text node.
00703       {
00704         out << getText(node);
00705       }
00706 
00707       break;
00708 
00709     case DOMNode::CDATA_SECTION_NODE:
00710       {
00711         // Probably need to put opening and closing sequences in by hand..
00712         out << "<![CDATA[" << getText(node) << "]]>";
00713       }
00714       break;
00715       
00716     case DOMNode::COMMENT_NODE :
00717       // glast.prs doesn't have any comments (but should!)
00718       // Note this won't indent correctly if the text node
00719       // contains multiple lines.  Could have utility routine
00720       // to do this, to be called for comments and text nodes
00721       {
00722         out << "<!-- " << getText(node) << "-->" << std::endl;
00723       }
00724 
00725       break;
00726     default:
00727       // ignore anything else
00728       break;
00729     }
00730   }
00731 
00732   void Dom::prune(DOMElement* elt) {
00733     DOMElement* child = findFirstChildByName(elt, "*");
00734     while (child != 0) {
00735       DOMElement* sib = getSiblingElement(child);
00736       prune(child);
00737       elt->removeChild(child);
00738       child = sib;
00739     }
00740   }
00741   char *Dom::transToChar(const XMLCh* const str) {
00742     return transToChar(str, XMLString::stringLen(str) );
00743   }
00744 
00745   char *Dom::transToChar(const XMLCh* const str, unsigned int len) {
00746     // Passing null argument is a fatal error.
00747     // No, it's not
00748     //    assert(str != 0);
00749     if (str == 0) return 0;
00750 
00751     if (!transcoder) {
00752       int status = initTrans();
00753       if (!status) return 0;
00754     }
00755 
00756     // Find length of str to pass to transcode(..) rather than
00757     // just passing output buffer size.  This is important because 
00758     // (for Xerces 1.3 anyway) the transcode routine will try to read 
00759     // this many bytes from the input buffer, conceivably causing
00760     // an access violation if it's more than the actual input
00761     // buffer length
00762     
00763     if (len + 1 > transBufSize) { // return old buffer; allocate a bigger one
00764       char * tBuf = new char[len + 1];
00765       if (!tBuf) return 0;
00766       transBufSize = len + 1;
00767       delete [] transBuf;
00768       transBuf = tBuf;
00769     }
00770 
00771     bool ok;
00772     ok = Dom::transcoder->transcode(str, transBuf, len);
00773     return ( ok ? transBuf : 0);
00774   }
00775 
00776 
00777   XMLCh* Dom::transToXMLCh(const char* const src) {
00778     // Passing null string is a fatal error
00779     // No, it's not
00780     if (src == 0) return 0;
00781     if (!transcoder) {
00782       int status = initTrans();
00783       if (!status) return 0;
00784     }
00785     // as with transToChar above, find actual length of char*
00786     // and pass that to Xerces utility for 3rd (maxChars) argument.
00787     unsigned int len = strlen(src) + 1;
00788     if (len  > xmlchBufSize) {
00789       XMLCh * tBuf = new XMLCh[len];
00790       if (!tBuf) return 0;
00791       xmlchBufSize = len;
00792       delete [] xmlchBuf;
00793       xmlchBuf = tBuf;
00794     }
00795 
00796     bool ok;
00797 
00798     ok = transcoder->transcode(src, xmlchBuf, len);
00799     return (ok ? xmlchBuf : 0);
00800   }
00801 
00802   int Dom::initTrans() {
00803     transcoder = XMLPlatformUtils::fgTransService->makeNewLCPTranscoder(
00804                                                                                 XMLPlatformUtils::fgMemoryManager
00805                                                                         );
00806     if (!transcoder) return 0;   // and complain?!? Shouldn't ever happen
00807     transBuf = new char[transBufSize];
00808     if (!transBuf) {
00809       delete transcoder;
00810       return 0;
00811     }
00812     xmlchBuf = new XMLCh[xmlchBufSize];
00813     if (!xmlchBuf) {
00814       delete [] transBuf;
00815       delete transcoder;
00816       return 0;
00817     }
00818     return 1;
00819   }
00820 
00821 }  // end namespace xmlBase

Generated on Tue Nov 29 22:57:57 2016 for BOSS_7.0.2 by  doxygen 1.4.7