Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

XmlUtils.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 #define LIBSMBIOS_SOURCE
00020 #include "XmlUtils.h"
00021 
00022 // no trailing ';' because macro already has one
00023 XERCES_CPP_NAMESPACE_USE
00024 
00025 using namespace std;
00026 
00027 namespace xmlutils
00028 {
00029     //
00030     // NON-MEMBER FUNCTIONS
00031     //
00032 
00033     // workaround for missing dynamic_cast on windows:
00034     // xerces not compiled with RTTI on windows
00035     // use this in place of:
00036     //      elem = dynamic_cast<DOMElement *>(node);
00037     DOMElement *castNode2Element( DOMNode *node )
00038     {
00039         DOMElement *elem = 0;
00040         if ( node->getNodeType() == DOMNode::ELEMENT_NODE )
00041         {
00042             elem = reinterpret_cast<DOMElement *>(node);
00043         }
00044         else
00045         {
00046             // workaround for gcc 2.96. Doesn't have bad_cast. :-(
00047             //throw std::bad_cast();
00048             throw smbios::Exception<smbios::IException>("could not reinterpret cast element to requested type.");
00049         }
00050         return elem;
00051     }
00052 
00053     // const version of function above.
00054     const DOMElement *castNode2Element( const DOMNode *node )
00055     {
00056         const DOMElement *elem = 0;
00057         if ( node->getNodeType() == DOMNode::ELEMENT_NODE )
00058         {
00059             elem = reinterpret_cast<const DOMElement *>(node);
00060         }
00061         else
00062         {
00063             // workaround for gcc 2.96. Doesn't have bad_cast. :-(
00064             //throw std::bad_cast();
00065             throw smbios::Exception<smbios::IException>("could not reinterpret cast element to requested type.");
00066         }
00067         return elem;
00068     }
00069 
00070     // even better
00071     string safeXMLChToString( const XMLCh *src )
00072     {
00073         string dest = "";
00074         if( src )
00075         {
00076             const char *temp = XMLString::transcode( src );
00077             dest = temp;
00078             delete [] const_cast<char *>(temp);
00079         }
00080         return dest;
00081     }
00082 
00083     // the best. use this when possible.
00084     string safeGetAttribute( const DOMNode *node, const string &attr )
00085     {
00086         const DOMElement *elem = castNode2Element(node);
00087 
00088         // extract type information
00089         XMLCh *attrName = X(attr.c_str()); // NEED TO 'release' !!!
00090         const XMLCh *attrValue = elem->getAttribute( attrName );
00091         XMLString::release(&attrName); // released.
00092 
00093         // return the type as an INT.
00094         return  safeXMLChToString( attrValue );
00095     }
00096 
00097     DOMBuilder *getParser( )
00098     {
00099         static const XMLCh gLS[] =
00100             {
00101                 chLatin_L, chLatin_S, chNull
00102             };
00103         DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
00104         DOMBuilder        *parser = (static_cast<DOMImplementationLS*>(impl))->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
00105         parser->setFeature( XMLUni::fgDOMNamespaces, false );
00106         parser->setFeature( XMLUni::fgXercesSchema, false );
00107         parser->setFeature( XMLUni::fgXercesSchemaFullChecking, false );
00108 
00109         parser->resetDocumentPool();
00110 
00111         return parser;
00112     }
00113 
00114     //
00115     // Finds a "STRUCTURE" element with the specified attribute and returns
00116     // a pointer to it.
00117     //
00118     DOMElement *findElement( DOMElement *root, const string elementName, const string &attribute, const string &value )
00119     {
00120         DOMElement *elem = 0;
00121 
00122         // If we don't have a ref to XML file, we cannot find this info
00123         if( ! root )
00124             throw NotFoundImpl("no root element ref to xml file, cannot findElement");
00125 
00126         XMLCh *tagName = X(elementName.c_str()); // NEED TO 'release' !!!
00127         DOMNodeList *structureList = root->getElementsByTagName(tagName);
00128         XMLString::release(&tagName);
00129 
00130         if( !structureList )
00131             throw NotFoundImpl("could not find element.");
00132 
00133         int length = structureList->getLength();
00134         for( int index = 0; (index < length) && !elem ; ++index )
00135         {
00136             DOMNode *node = structureList->item( index );
00137             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00138             {
00139                 string strAttrValue = safeGetAttribute( node, attribute );
00140                 if( (strAttrValue == value) || (attribute == "") )
00141                 {
00142                     elem = castNode2Element( node );
00143                 }
00144             }
00145         }
00146 
00147         if( ! elem )
00148             throw NotFoundImpl("could not find element.");
00149 
00150         return elem;
00151     }
00152 
00153     //
00154     // Finds a "STRUCTURE" element with the specified attribute and returns
00155     // a pointer to it.
00156     //
00157     DOMElement *findElementWithNumericAttr( DOMElement *root, const string elementName, const string &attribute, long value)
00158     {
00159         DOMElement *elem = 0;
00160 
00161         // If we don't have a ref to XML file, we cannot find this info
00162         if( ! root )
00163             throw NotFoundImpl("no root element ref to xml file, cannot findElement");
00164 
00165         XMLCh *tagName = X(elementName.c_str()); // NEED TO 'release' !!!
00166         DOMNodeList *structureList = root->getElementsByTagName(tagName);
00167         XMLString::release(&tagName);
00168 
00169         if( !structureList )
00170             throw NotFoundImpl("could not find element.");
00171 
00172         int length = structureList->getLength();
00173         for( int index = 0; (index < length) && !elem ; ++index )
00174         {
00175             DOMNode *node = structureList->item( index );
00176             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00177             {
00178                 string strAttrValue = safeGetAttribute( node, attribute );
00179                 char *endptr = 0;
00180                 long attrValue = strtol(strAttrValue.c_str(), &endptr, 0);
00181                 if(endptr == strAttrValue.c_str()) continue;
00182                 if((attrValue == value) || (attribute == "") )
00183                 {
00184                     elem = castNode2Element( node );
00185                 }
00186             }
00187         }
00188 
00189         if( ! elem )
00190             throw NotFoundImpl("could not find element.");
00191 
00192         return elem;
00193     }
00194 
00195     string getNodeText( DOMNode *elem )
00196     {
00197         string retval = "";
00198 
00199         DOMNodeList *children = elem->getChildNodes ();
00200 
00201         int length = children->getLength();
00202         for( int index = 0; index < length; ++index )
00203         {
00204             DOMNode *node = children->item( index );
00205             if( node->getNodeType() == DOMNode::TEXT_NODE  )
00206             {
00207                 DOMText *txt = reinterpret_cast<DOMText *>(node);
00208                 const XMLCh *src = txt->getNodeValue();
00209                 retval += safeXMLChToString(src);
00210             }
00211         }
00212         return retval;
00213     }
00214 
00215     int getNumberFromXmlAttr( DOMElement *element, const string field, int base )
00216     {
00217         int tempNum = 0;
00218         string tempStr = safeGetAttribute( element, field );
00219         if(tempStr.length() != 0)
00220             tempNum = strtol( tempStr.c_str(), 0, base);
00221 
00222         return tempNum;
00223     }
00224 }

Generated on Wed Apr 11 16:25:10 2007 for SMBIOS Library by doxygen 1.3.5