Home | History | Annotate | Download | only in xmlserializer
      1 /*
      2  * Copyright (c) 2011-2014, Intel Corporation
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification,
      6  * are permitted provided that the following conditions are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright notice, this
      9  * list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright notice,
     12  * this list of conditions and the following disclaimer in the documentation and/or
     13  * other materials provided with the distribution.
     14  *
     15  * 3. Neither the name of the copyright holder nor the names of its contributors
     16  * may be used to endorse or promote products derived from this software without
     17  * specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 #include "XmlElement.h"
     31 #include <libxml/tree.h>
     32 #include <stdlib.h>
     33 #include <sstream>
     34 
     35 using std::string;
     36 using std::ostringstream;
     37 
     38 CXmlElement::CXmlElement(_xmlNode* pXmlElement) : _pXmlElement(pXmlElement)
     39 {
     40 }
     41 
     42 CXmlElement::CXmlElement() : _pXmlElement(NULL)
     43 {
     44 }
     45 
     46 void CXmlElement::setXmlElement(_xmlNode* pXmlElement)
     47 {
     48     _pXmlElement = pXmlElement;
     49 }
     50 
     51 string CXmlElement::getType() const
     52 {
     53     return (const char*)_pXmlElement->name;
     54 }
     55 
     56 string CXmlElement::getPath() const
     57 {
     58     string strPathElement = "/" + getType();
     59 
     60     if (hasAttribute("Name")) {
     61 
     62         strPathElement += "[@Name=" + getNameAttribute() + "]";
     63     }
     64 
     65     CXmlElement parentElement;
     66 
     67     if (getParentElement(parentElement)) {
     68 
     69         // Done
     70         return parentElement.getPath() + strPathElement;
     71     }
     72     return strPathElement;
     73 }
     74 
     75 string CXmlElement::getNameAttribute() const
     76 {
     77     return getAttributeString("Name");
     78 }
     79 
     80 bool CXmlElement::hasAttribute(const string& strAttributeName) const
     81 {
     82     return xmlHasProp(_pXmlElement, (const xmlChar*)strAttributeName.c_str()) != NULL;
     83 }
     84 
     85 string CXmlElement::getAttributeString(const string &strAttributeName) const
     86 {
     87     if (!hasAttribute(strAttributeName)) {
     88 
     89         return "";
     90     }
     91     xmlChar* pucXmlValue = xmlGetProp((xmlNode*)_pXmlElement, (const xmlChar*)strAttributeName.c_str());
     92     if (pucXmlValue == NULL) {
     93         return "";
     94     }
     95 
     96     string strValue((const char*)pucXmlValue);
     97 
     98     xmlFree(pucXmlValue);
     99 
    100     return strValue;
    101 }
    102 
    103 bool CXmlElement::getAttributeBoolean(const string& strAttributeName, const string& strTrueValue) const
    104 {
    105     return getAttributeString(strAttributeName) == strTrueValue;
    106 }
    107 
    108 bool CXmlElement::getAttributeBoolean(const string& strAttributeName) const
    109 {
    110     string strAttributeValue(getAttributeString(strAttributeName));
    111 
    112     return strAttributeValue == "true" || strAttributeValue == "1";
    113 }
    114 
    115 uint32_t CXmlElement::getAttributeInteger(const string &strAttributeName) const
    116 {
    117     string strAttributeValue(getAttributeString(strAttributeName));
    118 
    119     return strtoul(strAttributeValue.c_str(), NULL, 0);
    120 }
    121 
    122 int32_t CXmlElement::getAttributeSignedInteger(const string &strAttributeName) const
    123 {
    124     string strAttributeValue(getAttributeString(strAttributeName));
    125 
    126     return strtol(strAttributeValue.c_str(), NULL, 0);
    127 }
    128 
    129 double CXmlElement::getAttributeDouble(const string &strAttributeName) const
    130 {
    131     string strAttributeValue(getAttributeString(strAttributeName));
    132 
    133     return strtod(strAttributeValue.c_str(), NULL);
    134 }
    135 
    136 string CXmlElement::getTextContent() const
    137 {
    138     xmlChar* pucXmlContent = xmlNodeGetContent(_pXmlElement);
    139     if (pucXmlContent == NULL) {
    140         return "";
    141     }
    142 
    143     string strContent((const char*)pucXmlContent);
    144 
    145     xmlFree(pucXmlContent);
    146 
    147     return strContent;
    148 }
    149 
    150 bool CXmlElement::getChildElement(const string& strType, CXmlElement& childElement) const
    151 {
    152     CChildIterator childIterator(*this);
    153 
    154     while (childIterator.next(childElement)) {
    155 
    156         if (childElement.getType() == strType) {
    157 
    158             return true;
    159         }
    160     }
    161     return false;
    162 }
    163 
    164 bool CXmlElement::getChildElement(const string& strType, const string& strNameAttribute, CXmlElement& childElement) const
    165 {
    166     CChildIterator childIterator(*this);
    167 
    168     while (childIterator.next(childElement)) {
    169 
    170         if ((childElement.getType() == strType) && (childElement.getNameAttribute() == strNameAttribute)) {
    171 
    172             return true;
    173         }
    174     }
    175     return false;
    176 }
    177 
    178 size_t CXmlElement::getNbChildElements() const
    179 {
    180     CXmlElement childElement;
    181     size_t uiNbChildren = 0;
    182 
    183     CChildIterator childIterator(*this);
    184 
    185     while (childIterator.next(childElement)) {
    186 
    187         uiNbChildren++;
    188     }
    189     return uiNbChildren;
    190 }
    191 
    192 bool CXmlElement::getParentElement(CXmlElement& parentElement) const
    193 {
    194     _xmlNode* pXmlNode = _pXmlElement->parent;
    195 
    196     if (pXmlNode->type == XML_ELEMENT_NODE) {
    197 
    198         parentElement.setXmlElement(pXmlNode);
    199 
    200         return true;
    201     }
    202     return false;
    203 }
    204 
    205 // Setters
    206 void CXmlElement::setAttributeBoolean(const string& strAttributeName, bool bValue)
    207 {
    208     setAttributeString(strAttributeName, bValue ? "true" : "false");
    209 }
    210 
    211 
    212 void CXmlElement::setAttributeString(const string& strAttributeName, const string& strValue)
    213 {
    214     xmlNewProp(_pXmlElement, BAD_CAST strAttributeName.c_str(), BAD_CAST strValue.c_str());
    215 }
    216 
    217 void CXmlElement::setAttributeInteger(const string& strAttributeName, uint32_t uiValue)
    218 {
    219    ostringstream strStream;
    220    strStream << uiValue;
    221    setAttributeString(strAttributeName, strStream.str());
    222 }
    223 
    224 void CXmlElement::setAttributeSignedInteger(const string& strAttributeName, int32_t iValue)
    225 {
    226    ostringstream strStream;
    227    strStream << iValue;
    228    setAttributeString(strAttributeName, strStream.str());
    229 }
    230 
    231 void CXmlElement::setNameAttribute(const string& strValue)
    232 {
    233     setAttributeString("Name", strValue);
    234 }
    235 
    236 void CXmlElement::setTextContent(const string& strContent)
    237 {
    238     xmlAddChild(_pXmlElement, xmlNewText(BAD_CAST strContent.c_str()));
    239 }
    240 
    241 // Child creation
    242 void CXmlElement::createChild(CXmlElement& childElement, const string& strType)
    243 {
    244 #ifdef LIBXML_TREE_ENABLED
    245     xmlNodePtr pChildNode = xmlNewChild(_pXmlElement, NULL, BAD_CAST strType.c_str(), NULL);
    246 
    247     childElement.setXmlElement(pChildNode);
    248 #endif
    249 }
    250 
    251 // Child iteration
    252 CXmlElement::CChildIterator::CChildIterator(const CXmlElement& xmlElement) : _pCurNode(xmlElement._pXmlElement->children)
    253 {
    254 }
    255 
    256 bool CXmlElement::CChildIterator::next(CXmlElement& xmlChildElement)
    257 {
    258     while (_pCurNode) {
    259 
    260         if (_pCurNode->type == XML_ELEMENT_NODE) {
    261 
    262             xmlChildElement.setXmlElement(_pCurNode);
    263 
    264             _pCurNode = _pCurNode->next;
    265 
    266             return true;
    267         }
    268         _pCurNode = _pCurNode->next;
    269     }
    270 
    271     return false;
    272 }
    273 
    274