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 XERCES_CPP_NAMESPACE_USE;
00023 using namespace std;
00024 
00025 namespace xmlutils
00026 {
00027     //
00028     // NON-MEMBER FUNCTIONS
00029     //
00030 
00031     // workaround for missing dynamic_cast on windows:
00032     // xerces not compiled with RTTI on windows
00033     // use this in place of:
00034     //      elem = dynamic_cast<DOMElement *>(node);
00035     DOMElement *castNode2Element( DOMNode *node )
00036     {
00037         DOMElement *elem = 0;
00038         if ( node->getNodeType() == DOMNode::ELEMENT_NODE )
00039         {
00040             elem = reinterpret_cast<DOMElement *>(node);
00041         }
00042         else
00043         {
00044             // workaround for gcc 2.96. Doesn't have bad_cast. :-(
00045             //throw std::bad_cast();
00046             throw smbios::Exception<smbios::IException>("could not reinterpret cast element to requested type.");
00047         }
00048         return elem;
00049     }
00050 
00051     // const version of function above.
00052     const DOMElement *castNode2Element( const DOMNode *node )
00053     {
00054         const DOMElement *elem = 0;
00055         if ( node->getNodeType() == DOMNode::ELEMENT_NODE )
00056         {
00057             elem = reinterpret_cast<const DOMElement *>(node);
00058         }
00059         else
00060         {
00061             // workaround for gcc 2.96. Doesn't have bad_cast. :-(
00062             //throw std::bad_cast();
00063             throw smbios::Exception<smbios::IException>("could not reinterpret cast element to requested type.");
00064         }
00065         return elem;
00066     }
00067 
00068     // even better
00069     string safeXMLChToString( const XMLCh *src )
00070     {
00071         string dest = "";
00072         if( src )
00073         {
00074             const char *temp = XMLString::transcode( src );
00075             dest = temp;
00076             delete [] const_cast<char *>(temp);
00077         }
00078         return dest;
00079     }
00080 
00081     // the best. use this when possible.
00082     string safeGetAttribute( const DOMNode *node, const string &attr )
00083     {
00084         const DOMElement *elem = castNode2Element(node);
00085 
00086         // extract type information
00087         XMLCh *attrName = X(attr.c_str()); // NEED TO 'release' !!!
00088         const XMLCh *attrValue = elem->getAttribute( attrName );
00089         XMLString::release(&attrName); // released.
00090 
00091         // return the type as an INT.
00092         return  safeXMLChToString( attrValue );
00093     }
00094 
00095     DOMBuilder *getParser( )
00096     {
00097         static const XMLCh gLS[] =
00098             {
00099                 chLatin_L, chLatin_S, chNull
00100             };
00101         DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
00102         DOMBuilder        *parser = (static_cast<DOMImplementationLS*>(impl))->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
00103         parser->setFeature( XMLUni::fgDOMNamespaces, false );
00104         parser->setFeature( XMLUni::fgXercesSchema, false );
00105         parser->setFeature( XMLUni::fgXercesSchemaFullChecking, false );
00106 
00107         parser->resetDocumentPool();
00108 
00109         return parser;
00110     }
00111 
00112     //
00113     // Finds a "STRUCTURE" element with the specified attribute and returns
00114     // a pointer to it.
00115     //
00116     DOMElement *findElement( DOMElement *root, const string elementName, const string &attribute, const string &value )
00117     {
00118         DOMElement *elem = 0;
00119 
00120         // If we don't have a ref to XML file, we cannot find this info
00121         if( ! root )
00122             throw NotFoundImpl("no root element ref to xml file, cannot findElement");
00123 
00124         XMLCh *tagName = X(elementName.c_str()); // NEED TO 'release' !!!
00125         DOMNodeList *structureList = root->getElementsByTagName(tagName);
00126         XMLString::release(&tagName);
00127 
00128         if( !structureList )
00129             throw NotFoundImpl("could not find element.");
00130 
00131         int length = structureList->getLength();
00132         for( int index = 0; (index < length) && !elem ; ++index )
00133         {
00134             DOMNode *node = structureList->item( index );
00135             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00136             {
00137                 string strAttrValue = safeGetAttribute( node, attribute );
00138                 if( (strAttrValue == value) || (attribute == "") )
00139                 {
00140                     elem = castNode2Element( node );
00141                 }
00142             }
00143         }
00144 
00145         if( ! elem )
00146             throw NotFoundImpl("could not find element.");
00147 
00148         return elem;
00149     }
00150 
00151     //
00152     // Finds a "STRUCTURE" element with the specified attribute and returns
00153     // a pointer to it.
00154     //
00155     DOMElement *findElementWithNumericAttr( DOMElement *root, const string elementName, const string &attribute, long value)
00156     {
00157         DOMElement *elem = 0;
00158 
00159         // If we don't have a ref to XML file, we cannot find this info
00160         if( ! root )
00161             throw NotFoundImpl("no root element ref to xml file, cannot findElement");
00162 
00163         XMLCh *tagName = X(elementName.c_str()); // NEED TO 'release' !!!
00164         DOMNodeList *structureList = root->getElementsByTagName(tagName);
00165         XMLString::release(&tagName);
00166 
00167         if( !structureList )
00168             throw NotFoundImpl("could not find element.");
00169 
00170         int length = structureList->getLength();
00171         for( int index = 0; (index < length) && !elem ; ++index )
00172         {
00173             DOMNode *node = structureList->item( index );
00174             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00175             {
00176                 string strAttrValue = safeGetAttribute( node, attribute );
00177                 char *endptr = 0;
00178                 long attrValue = strtol(strAttrValue.c_str(), &endptr, 0);
00179                 if(endptr == strAttrValue.c_str()) continue;
00180                 if((attrValue == value) || (attribute == "") )
00181                 {
00182                     elem = castNode2Element( node );
00183                 }
00184             }
00185         }
00186 
00187         if( ! elem )
00188             throw NotFoundImpl("could not find element.");
00189 
00190         return elem;
00191     }
00192 
00193     string getNodeText( DOMNode *elem )
00194     {
00195         string retval = "";
00196 
00197         DOMNodeList *children = elem->getChildNodes ();
00198 
00199         int length = children->getLength();
00200         for( int index = 0; index < length; ++index )
00201         {
00202             DOMNode *node = children->item( index );
00203             if( node->getNodeType() == DOMNode::TEXT_NODE  )
00204             {
00205                 DOMText *txt = reinterpret_cast<DOMText *>(node);
00206                 const XMLCh *src = txt->getNodeValue();
00207                 retval += safeXMLChToString(src);
00208             }
00209         }
00210         return retval;
00211     }
00212 
00213     int getNumberFromXmlAttr( DOMElement *element, const string field, int base )
00214     {
00215         int tempNum = 0;
00216         string tempStr = safeGetAttribute( element, field );
00217         if(tempStr.length() != 0)
00218             tempNum = strtol( tempStr.c_str(), 0, base);
00219 
00220         return tempNum;
00221     }
00222 }

Generated on Tue Jan 17 02:59:08 2006 for SMBIOS Library by  doxygen 1.4.6