00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <Sockets/Parse.h>
00024 #include "XmlNode.h"
00025 #include "XmlDocument.h"
00026 #include "XmlException.h"
00027
00028 namespace Xmlw {
00029
00030
00031 XmlNode::XmlNode(XmlDocument& doc)
00032 : m_doc(doc)
00033 , m_current( GetRootElement() )
00034 {
00035 }
00036
00037
00038 XmlNode::XmlNode(XmlDocument& doc, const std::string& nodepath)
00039 : m_doc(doc)
00040 , m_current( GetRootElement() )
00041 {
00042 xmlNodePtr p = GetFirstElement( nodepath );
00043 SetCurrent( p );
00044 }
00045
00046
00047 XmlNode::XmlNode(const XmlNode& node, const std::string& nodepath)
00048 : m_doc( node.GetDocument() )
00049 , m_current( node )
00050 {
00051 xmlNodePtr p = GetFirstElement( node, nodepath );
00052 SetCurrent( p );
00053 }
00054
00055
00056 XmlNode::XmlNode(XmlDocument& doc, xmlNodePtr ptr)
00057 : m_doc(doc)
00058 , m_current( ptr )
00059 {
00060 }
00061
00062
00063 XmlNode::XmlNode(xmlDocPtr doc, xmlNodePtr ptr)
00064 : m_doc(doc)
00065 , m_current( ptr )
00066 {
00067 }
00068
00069
00070 XmlNode::~XmlNode()
00071 {
00072 }
00073
00074
00075 xmlNodePtr XmlNode::GetRootElement() const
00076 {
00077 m_current = xmlDocGetRootElement(m_doc);
00078 return m_current;
00079 }
00080
00081
00082 std::string XmlNode::GetProperty(const std::string& name) const
00083 {
00084 xmlChar *p = m_current ? xmlGetProp(m_current, (const xmlChar *) name.c_str() ) : NULL;
00085 if (!p)
00086 {
00087 throw XmlException( "Property '" + name + "' not found in node: " + GetNodeName() );
00088 }
00089 std::string str = (char *)p;
00090 xmlFree(p);
00091 return FromUtf8(str);
00092 }
00093
00094
00095 bool XmlNode::PropertyExists(const std::string& name) const
00096 {
00097 xmlChar *p = m_current ? xmlGetProp(m_current, (const xmlChar *) name.c_str() ) : NULL;
00098 if (!p)
00099 {
00100 return false;
00101 }
00102 xmlFree(p);
00103 return true;
00104 }
00105
00106
00107 xmlNodePtr XmlNode::GetChildrenNode() const
00108 {
00109 m_current = m_current ? m_current -> xmlChildrenNode : NULL;
00110 return m_current;
00111 }
00112
00113
00114 xmlNodePtr XmlNode::GetNextNode() const
00115 {
00116 do
00117 {
00118 m_current = m_current ? m_current -> next : NULL;
00119 } while (m_current && xmlIsBlankNode( m_current ));
00120 return m_current;
00121 }
00122
00123
00124 const std::string& XmlNode::GetNodeName() const
00125 {
00126 if (m_current)
00127 {
00128 m_current_name = FromUtf8((char *)m_current -> name);
00129 }
00130 else
00131 {
00132 m_current_name = "";
00133 }
00134 return m_current_name;
00135 }
00136
00137
00138 const std::string& XmlNode::GetContent() const
00139 {
00140 m_content = "";
00141 if (m_current)
00142 {
00143 xmlNodePtr p = m_current;
00144 xmlNodePtr p2 = GetChildrenNode();
00145 if (p2 && p2 -> content)
00146 {
00147 m_content = FromUtf8((char *)p2 -> content);
00148 }
00149 SetCurrent(p);
00150 }
00151 return m_content;
00152 }
00153
00154
00155 xmlNsPtr XmlNode::GetNodeNs() const
00156 {
00157 if (m_current)
00158 return m_current -> ns;
00159 return NULL;
00160 }
00161
00162
00163 const std::string& XmlNode::GetNodeNsPrefix() const
00164 {
00165 if (m_current && m_current -> ns && m_current -> ns -> prefix)
00166 {
00167 m_ns_prefix = FromUtf8((char *)m_current -> ns -> prefix);
00168 }
00169 else
00170 {
00171 m_ns_prefix = "";
00172 }
00173 return m_ns_prefix;
00174 }
00175
00176
00177 const std::string& XmlNode::GetNodeNsHref() const
00178 {
00179 if (m_current && m_current -> ns && m_current -> ns -> href)
00180 {
00181 m_ns_href = FromUtf8((char *)m_current -> ns -> href);
00182 }
00183 else
00184 {
00185 m_ns_href = "";
00186 }
00187 return m_ns_href;
00188 }
00189
00190
00191 xmlNodePtr XmlNode::GetFirstElement(const std::string& name) const
00192 {
00193 if (m_lookup_name.empty())
00194 m_lookup_name = name;
00195 GetRootElement();
00196 xmlNodePtr p = GetChildrenNode();
00197 while (p)
00198 {
00199 if (name == GetNodeName())
00200 {
00201 return p;
00202 }
00203 p = GetNextNode();
00204 }
00205 return NULL;
00206 }
00207
00208
00209 xmlNodePtr XmlNode::GetFirstElement(xmlNodePtr base,const std::string& name) const
00210 {
00211 if (m_lookup_name.empty())
00212 m_lookup_name = name;
00213 SetCurrent(base);
00214 xmlNodePtr p = GetChildrenNode();
00215 while (p)
00216 {
00217 if (name == GetNodeName())
00218 {
00219 return p;
00220 }
00221 p = GetNextNode();
00222 }
00223 return NULL;
00224 }
00225
00226
00227 xmlNodePtr XmlNode::GetNextElement(xmlNodePtr p,const std::string& name) const
00228 {
00229 SetCurrent(p);
00230 p = GetNextNode();
00231 while (p)
00232 {
00233 if (name == GetNodeName())
00234 {
00235 return p;
00236 }
00237 p = GetNextNode();
00238 }
00239 return NULL;
00240 }
00241
00242
00243 std::string XmlNode::FromUtf8(const std::string& str) const
00244 {
00245 if (!str.size())
00246 return "";
00247 std::string r;
00248 for (size_t i = 0; i < str.size(); i++)
00249 {
00250 if (i < str.size() - 1 && (str[i] & 0xe0) == 0xc0 && (str[i + 1] & 0xc0) == 0x80)
00251 {
00252 int c1 = str[i] & 0x1f;
00253 int c2 = str[++i] & 0x3f;
00254 int c = (c1 << 6) + c2;
00255 r += (char)c;
00256 }
00257 else
00258 {
00259 r += str[i];
00260 }
00261 }
00262 return r;
00263 }
00264
00265
00266 XmlNode::operator xmlNodePtr() const
00267 {
00268 return m_current;
00269 }
00270
00271
00272 XmlNode XmlNode::operator[](const std::string& name) const
00273 {
00274 xmlNodePtr p0 = m_current;
00275 xmlNodePtr p = GetFirstElement( m_current, name );
00276 SetCurrent( p0 );
00277 if (p)
00278 return XmlNode( m_doc, p );
00279 throw XmlException("Didn't find node: " + name);
00280 }
00281
00282
00283 bool XmlNode::Exists(const std::string& name) const
00284 {
00285 xmlNodePtr p0 = m_current;
00286 xmlNodePtr p = GetFirstElement( m_current, name );
00287 SetCurrent( p0 );
00288 if (p)
00289 return true;
00290 return false;
00291 }
00292
00293
00294 void XmlNode::operator++() const
00295 {
00296 GetNextNode();
00297 while (m_current)
00298 {
00299 if (m_lookup_name == GetNodeName())
00300 {
00301 return;
00302 }
00303 GetNextNode();
00304 }
00305 }
00306
00307
00308 std::map<std::string, std::string> XmlNode::GetNsMap() const
00309 {
00310 xmlNsPtr *p = xmlGetNsList(m_doc, m_current);
00311 std::map<std::string, std::string> vec;
00312 int i = 0;
00313 while (p[i])
00314 {
00315 std::string href = FromUtf8((char *)p[i] -> href);
00316 std::string prefix = p[i] -> prefix ? FromUtf8((char *)p[i] -> prefix) : "";
00317 vec[prefix] = href;
00318 ++i;
00319 }
00320 return vec;
00321 }
00322
00323
00324 std::map<std::string, std::string> XmlNode::GetNsMapRe() const
00325 {
00326 xmlNsPtr *p = xmlGetNsList(m_doc, m_current);
00327 std::map<std::string, std::string> vec;
00328 int i = 0;
00329 while (p[i])
00330 {
00331 std::string href = FromUtf8((char *)p[i] -> href);
00332 std::string prefix = p[i] -> prefix ? FromUtf8((char *)p[i] -> prefix) : "";
00333 vec[href] = prefix;
00334 if (!p[i] -> next)
00335 break;
00336 ++i;
00337 }
00338 return vec;
00339 }
00340
00341
00342 }