Home | History | Annotate | Download | only in xml
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include <util/xml/DomExpatAgent.h>
     17 #include <util/xml/XMLElementImpl.h>
     18 #include <ustring.h>
     19 #include <uios.h>
     20 using namespace ustl;
     21 
     22 /** see DomExpatAgent.h */
     23 DomExpatAgent::DomExpatAgent(XMLDocumentImpl* xmlDocPtr)
     24 {
     25     mXMLDocumentPtr = xmlDocPtr;
     26     mTopElementPtr = NULL;
     27 }
     28 
     29 /** see DomExpatAgent.h */
     30 DomExpatAgent::~DomExpatAgent()
     31 {
     32 
     33 }
     34 
     35 /** see DomExpatAgent.h */
     36 bool DomExpatAgent::generateDocumentFromXML(istringstream *xmlStream)
     37 {
     38     char ch;
     39     string content;
     40 
     41     if (NULL == mXMLDocumentPtr || NULL == xmlStream)
     42     {
     43         return false;
     44     }
     45 
     46     while ((ch = xmlStream->get()) != '\0')
     47     {
     48         content += ch;
     49     }
     50 
     51     if (ExpatWrapper::decode(content.c_str(), content.length(), 1) == 0)
     52 
     53     {
     54         return false;
     55     }
     56     return true;
     57 }
     58 
     59 /** see DomExpatAgent.h */
     60 void DomExpatAgent::pushTag(const DOMString *name, const XML_Char **atts)
     61 {
     62     ElementImpl *elementNode = mXMLDocumentPtr->createElement(name);
     63 
     64     if (NULL == elementNode)
     65     {
     66         return;
     67     }
     68 
     69     if (NULL != atts)
     70     {
     71         while (NULL != *atts)
     72         {
     73             //set attributes into element node.
     74             DOMString key(atts[0]), value(atts[1]);
     75             elementNode->setAttribute(&key, &value);
     76             atts += 2;
     77         }
     78     }
     79 
     80    if (!mStack.empty())
     81    {
     82        mTopElementPtr->appendChild(elementNode);
     83    }
     84    else
     85    {
     86        mXMLDocumentPtr->setFirstChild(elementNode);
     87    }
     88 
     89    mTopElementPtr = (XMLElementImpl *)elementNode;
     90    mStack.push_back(elementNode);
     91 }
     92 
     93 /** see DomExpatAgent.h */
     94 void DomExpatAgent::popTag(const DOMString *name)
     95 {
     96     if (NULL == name)
     97     {
     98         return;
     99     }
    100 
    101     if (mTopElementPtr != NULL)
    102     {
    103         if (!name->compare(mTopElementPtr->getTagName()->c_str()))
    104         {
    105             mStack.pop_back();
    106             if (!mStack.empty())
    107             {
    108                 mTopElementPtr =(XMLElementImpl *) mStack.back();
    109             }
    110             else
    111             {
    112                 mTopElementPtr = NULL;
    113             }
    114         }
    115     }
    116 }
    117 
    118 /** see DomExpatAgent.h */
    119 void DomExpatAgent::appendText(const DOMString *text)
    120 {
    121     if ((mTopElementPtr != NULL) && (text != NULL))
    122     {
    123         TextImpl *textNode = mXMLDocumentPtr->createTextNode(text);
    124 
    125         if (NULL == textNode)
    126         {
    127             return;
    128         }
    129 
    130        mTopElementPtr->appendChild(textNode);
    131     }
    132 }
    133 
    134 /** see DomExpatAgent.h */
    135 void DomExpatAgent::startElement(const XML_Char *name, const XML_Char **atts)
    136 {
    137     if (name)
    138     {
    139         DOMString tagName(name);
    140 
    141         pushTag(&tagName, atts);
    142     }
    143 }
    144 
    145 /** see DomExpatAgent.h */
    146 void DomExpatAgent::dataHandler(const XML_Char *s, int len)
    147 {
    148     if (s != NULL && len >= 1 && *s != '\n')
    149     {
    150         DOMString text;
    151         text.assign((char*)s, len);
    152         appendText(&text);
    153     }
    154 }
    155 
    156 /** see DomExpatAgent.h */
    157 void DomExpatAgent::endElement(const XML_Char *name)
    158 {
    159    if (name)
    160    {
    161        DOMString tagName(name);
    162        popTag(&tagName);
    163    }
    164 }
    165 
    166 /** see DomExpatAgent.h */
    167 ostringstream* DomExpatAgent::generateXMLFromDocument()
    168 {
    169     if (NULL == mXMLDocumentPtr)
    170     {
    171         return NULL;
    172     }
    173 
    174     ElementImpl *root = mXMLDocumentPtr->getDocumentElement();
    175 
    176     traverse(root);
    177 
    178     return &mXMLostream;
    179 }
    180 
    181 /** see DomExpatAgent.h */
    182 void DomExpatAgent::traverse(ElementImpl *root)
    183 {
    184     if (NULL == root)
    185     {
    186         return;
    187     }
    188 
    189     mXMLostream << "<" << *(root->getNodeName());
    190 
    191     if (root->hasAttributes())
    192     {
    193         mXMLostream << endl;
    194         const DOMStringMap* attrMapPtr = (static_cast<XMLElementImpl*>(root))->getAttributeMap();
    195         DOMStringMap::const_reverse_iterator pos;
    196 
    197         for (pos=attrMapPtr->rbegin(); pos != attrMapPtr->rend(); pos++)
    198         {
    199             mXMLostream << pos->first << "=" << "\"" << pos->second << "\"";
    200 
    201             if (pos + 1 != attrMapPtr->rend())
    202             {
    203                 mXMLostream << endl;
    204             }
    205         }
    206     }
    207 
    208     mXMLostream << ">" << endl;
    209 
    210     NodeImpl *child = root->getFirstChild();
    211 
    212     while (child != NULL)
    213     {
    214         NodeType what = child->getNodeType();
    215 
    216         if (what == ELEMENT_NODE)
    217         {
    218             traverse(static_cast<ElementImpl*>(child));
    219         } else if (what == TEXT_NODE)
    220         {
    221             mXMLostream << *(static_cast<TextImpl*>(child)->getData()) << endl;
    222         }
    223 
    224         child = child->getNextSibling();
    225     }
    226 
    227     mXMLostream << "</" << *(root->getNodeName()) << ">" << endl;
    228 }
    229