00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_XMLPullParser.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_Assertion.hpp"
00040 #include "OW_XMLUnescape.hpp"
00041 #include "OW_XMLParseException.hpp"
00042 #include <algorithm>
00043
00044 namespace OW_NAMESPACE
00045 {
00046
00048 XMLPullParser::~XMLPullParser()
00049 {
00050 }
00051
00053 void
00054 XMLPullParser::prime()
00055 {
00056 if (!(m_good = m_parser.next(m_curTok)))
00057 {
00058 OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00059 }
00060 if (m_curTok.type == XMLToken::XML_DECLARATION)
00061 {
00062 if (!(m_good = m_parser.next(m_curTok)))
00063 {
00064 OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00065 }
00066 skipData();
00067 }
00068 if (m_curTok.type == XMLToken::DOCTYPE)
00069 {
00070 if (!(m_good = m_parser.next(m_curTok)))
00071 {
00072 OW_THROWXML(XMLParseException::SEMANTIC_ERROR, "Empty XML");
00073 }
00074 skipData();
00075 }
00076 }
00078 XMLPullParser::XMLPullParser(const String& str)
00079 : m_ptfs(new TempFileStream())
00080 , m_parser()
00081 , m_curTok()
00082 , m_good(true)
00083 {
00084 *m_ptfs << str;
00085 m_parser.setInput(*m_ptfs);
00086 prime();
00087 }
00089 XMLPullParser::XMLPullParser(std::istream& istr)
00090 : m_ptfs()
00091 , m_parser(istr)
00092 , m_curTok()
00093 , m_good(true)
00094 {
00095 prime();
00096 }
00098 XMLPullParser::XMLPullParser()
00099 : m_good(false)
00100 {
00101 }
00102
00104 String
00105 XMLPullParser::getAttribute(const char* const attrId, bool throwIfError) const
00106 {
00107 OW_ASSERT(m_curTok.type == XMLToken::START_TAG);
00108 for (unsigned i = 0; i < m_curTok.attributeCount; i++)
00109 {
00110 const XMLToken::Attribute& attr = m_curTok.attributes[i];
00111
00112 if (attr.name.equals(attrId))
00113 {
00114 return XMLUnescape(attr.value.c_str(), attr.value.length());
00115 }
00116 }
00117 if (throwIfError)
00118 {
00119 OW_THROWXML(XMLParseException::BAD_ATTRIBUTE_NAME,
00120 Format("Failed to find "
00121 "attribute: %1 in node: %2", attrId, m_curTok.text).c_str() );
00122 }
00123 return String();
00124 }
00126 void
00127 XMLPullParser::mustGetChild()
00128 {
00129 if (!m_good)
00130 {
00131 m_good = false;
00132 OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00133 Format("XMLPullParser::mustGetChild() failed. parser = %1",
00134 *this).c_str());
00135 }
00136 getChild();
00137 if (!m_good)
00138 {
00139 m_good = false;
00140 OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00141 Format("XMLPullParser::mustGetChild() failed. parser = %1",
00142 *this).c_str());
00143 }
00144 }
00146 void
00147 XMLPullParser::getChild()
00148 {
00149 if (!m_good)
00150 {
00151 return;
00152 }
00153 for (;;)
00154 {
00155 nextToken();
00156 if (!m_good)
00157 {
00158 return;
00159 }
00160 switch (m_curTok.type)
00161 {
00162 case XMLToken::END_TAG:
00163 m_good = false;
00164 case XMLToken::START_TAG:
00165 return;
00166 default:
00167 break;
00168 }
00169 }
00170 }
00172 void
00173 XMLPullParser::getNextTag(bool throwIfError)
00174 {
00175 nextToken();
00176 skipData();
00177 if (!m_good && throwIfError)
00178 {
00179 OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00180 Format("XMLPullParser::getNext() failed. parser = %1",
00181 *this).c_str());
00182 }
00183 }
00185 void
00186 XMLPullParser::getNext(bool throwIfError)
00187 {
00188 nextToken();
00189 if (!m_good && throwIfError)
00190 {
00191 OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00192 Format("XMLPullParser::getNext() failed. parser = %1",
00193 *this).c_str());
00194 }
00195 }
00197 void
00198 XMLPullParser::mustGetEndTag()
00199 {
00200 skipData();
00201 if (m_curTok.type != XMLToken::END_TAG)
00202 {
00203 OW_THROWXML(XMLParseException::SEMANTIC_ERROR,
00204 Format("XMLPullParser::mustGetEndTag() failed. parser = %1",
00205 *this).c_str());
00206 }
00207 getNext();
00208 skipData();
00209 }
00211 String
00212 XMLPullParser::getName() const
00213 {
00214 OW_ASSERT(m_curTok.type == XMLToken::START_TAG || m_curTok.type == XMLToken::END_TAG);
00215 return XMLUnescape(m_curTok.text.c_str(), m_curTok.text.length());
00216 }
00218 String
00219 XMLPullParser::getData() const
00220 {
00221 OW_ASSERT(m_curTok.type == XMLToken::CONTENT || m_curTok.type == XMLToken::CDATA);
00222 return XMLUnescape(m_curTok.text.c_str(), m_curTok.text.length());
00223 }
00225 bool
00226 XMLPullParser::isData() const
00227 {
00228 return m_curTok.type == XMLToken::CONTENT || m_curTok.type == XMLToken::CDATA;
00229 }
00231 void
00232 XMLPullParser::nextToken()
00233 {
00234 do
00235 {
00236 m_good = m_parser.next(m_curTok);
00237 } while (m_curTok.type == XMLToken::COMMENT && m_good);
00238 }
00240 void
00241 XMLPullParser::skipData()
00242 {
00243 while (isData() && m_good)
00244 {
00245 nextToken();
00246 }
00247 }
00249 std::ostream& operator<<(std::ostream& ostr, const XMLPullParser& p)
00250 {
00251 ostr << "m_good = " << p.m_good << '\n';
00252 switch (p.m_curTok.type)
00253 {
00254 case XMLToken::INVALID:
00255 ostr << "*INVALID*\n";
00256 break;
00257 case XMLToken::XML_DECLARATION:
00258 ostr << "<xml>\n";
00259 break;
00260 case XMLToken::START_TAG:
00261 ostr << '<' << p.m_curTok.text << ' ';
00262 for (unsigned int x = 0; x < p.m_curTok.attributeCount; ++x)
00263 {
00264 ostr << p.m_curTok.attributes[x].name << "=\"" <<
00265 p.m_curTok.attributes[x].value << "\" ";
00266 }
00267 ostr << ">\n";
00268 break;
00269 case XMLToken::END_TAG:
00270 ostr << "</" << p.m_curTok.text << ">\n";
00271 break;
00272 case XMLToken::COMMENT:
00273 ostr << "<--" << p.m_curTok.text << "-->\n";
00274 break;
00275 case XMLToken::CDATA:
00276 ostr << "<CDATA[[" << p.m_curTok.text << "]]>\n";
00277 break;
00278 case XMLToken::DOCTYPE:
00279 ostr << "<DOCTYPE>\n";
00280 break;
00281 case XMLToken::CONTENT:
00282 ostr << "CONTENT: " << p.m_curTok.text << '\n';
00283 break;
00284 default:
00285 ostr << "Unknown token type\n";
00286 }
00287 return ostr;
00288 }
00289
00290 }
00291