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