|
reSIProcate/stack
9373
|
00001 #include "resip/stack/XMLCursor.hxx" 00002 #include "rutil/DataStream.hxx" 00003 #include "rutil/Inserter.hxx" 00004 #include "rutil/Logger.hxx" 00005 00006 #include <iostream> 00007 00008 #include <cassert> 00009 00010 using namespace resip; 00011 using namespace std; 00012 00013 /* 00014 <foo/> 00015 <foo></foo> 00016 <foo>some contents</foo> 00017 <foo><echild/><child>first</child><child>second</child></foo> 00018 <foo bar="baz" qwerty = "quux"/> 00019 <foo bar="baz" qwerty = "quux">contents</foo> 00020 */ 00021 00022 void traverse(XMLCursor& c) 00023 { 00024 if (c.firstChild()) 00025 { 00026 traverse(c); 00027 c.parent(); 00028 } 00029 00030 // process(c); 00031 std::cerr << c.getTag() << std::endl; 00032 00033 if (c.nextSibling()) 00034 { 00035 traverse(c); 00036 } 00037 } 00038 00039 int 00040 main() 00041 { 00042 Log::initialize(Log::Cout, Log::Stack, "testXMLCursor"); 00043 00044 { 00045 const Data test( 00046 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" 00047 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\r\n" 00048 " xmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\r\n" 00049 " xmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\r\n" 00050 " entity=\"sip:chris@xxx.xx.xxx.xx\">\r\n" 00051 " <pp:person>\r\n" 00052 " <status>\r\n" 00053 " <ep:activities>\r\n" 00054 " <ep:activity>away</ep:activity>\r\n" 00055 " </ep:activities>\r\n" 00056 " </status>\r\n" 00057 " </pp:person>\r\n" 00058 " <tuple id=\"9b6yhF2Gk37o4\" >\r\n" 00059 " <status><basic>open</basic></status>\r\n" 00060 " </tuple>\r\n" 00061 "</presence>"); 00062 00063 try 00064 { 00065 XMLCursor xmlc(ParseBuffer(test.data(), test.size())); 00066 00067 assert(xmlc.getTag() == "presence"); 00068 traverse(xmlc); 00069 } 00070 catch (ParseException& e) 00071 { 00072 cerr << e << endl; 00073 assert(false); 00074 } 00075 } 00076 00077 // Tests for XML comment handling 00078 { 00079 const Data test( 00080 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" 00081 "<!--Comment1-->\r\n" 00082 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\r\n" 00083 " xmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\r\n" 00084 " xmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\r\n" 00085 " entity=\"sip:chris@xxx.xx.xxx.xx\">\r\n" 00086 "<!--Comment2-->\r\n" 00087 " <pp:person>\r\n" 00088 " <status>\r\n" 00089 " <!--Comment3-->\r\n" 00090 " <ep:activities>\r\n" 00091 " <ep:activity>away</ep:activity>\r\n" 00092 " </ep:activities>\r\n" 00093 " </status>\r\n" 00094 " </pp:person>\r\n" 00095 " <tuple id=\"9b6yhF2Gk37o4\" >\r\n" 00096 " <status><basic>open</basic></status>\r\n" 00097 "<!--Comment4-->\r\n" 00098 " </tuple>\r\n" 00099 "<!--Comment5-->\r\n" 00100 "</presence>" 00101 "<!--Comment6-->\r\n"); 00102 00103 try 00104 { 00105 XMLCursor xmlc(ParseBuffer(test.data(), test.size())); 00106 00107 assert(xmlc.getTag() == "presence"); 00108 traverse(xmlc); 00109 } 00110 catch (ParseException& e) 00111 { 00112 cerr << e << endl; 00113 assert(false); 00114 } 00115 } 00116 00117 // test assume that whitespace is not significant 00118 // may eventually be controlled by the document/element 00119 // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space 00120 assert(!XMLCursor::WhitespaceSignificant); 00121 00122 { 00123 cerr << "test attributes in self-terminating tag" << endl; 00124 Data contents("<?xml version=\"1.0\"?><root><foo attr=\"true\"/></root>"); 00125 try 00126 { 00127 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00128 00129 assert(xmlc.getTag() == "root"); 00130 assert(xmlc.getValue().empty()); 00131 assert(xmlc.getAttributes().empty()); 00132 assert(xmlc.atRoot()); 00133 assert(!xmlc.atLeaf()); 00134 assert(!xmlc.parent()); 00135 assert(xmlc.firstChild()); 00136 assert(xmlc.getValue().empty()); 00137 assert(!xmlc.getAttributes().empty()); 00138 assert(!xmlc.nextSibling()); 00139 } 00140 catch (ParseException& e) 00141 { 00142 cerr << e << endl; 00143 assert(false); 00144 } 00145 } 00146 00147 { 00148 cerr << "test empty root" << endl; 00149 Data contents("<?xml version=\"1.0\"?><foo/>"); 00150 try 00151 { 00152 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00153 00154 assert(xmlc.getTag() == "foo"); 00155 assert(xmlc.getValue().empty()); 00156 assert(xmlc.getAttributes().empty()); 00157 assert(xmlc.atRoot()); 00158 assert(!xmlc.atLeaf()); 00159 assert(!xmlc.parent()); 00160 assert(!xmlc.firstChild()); 00161 xmlc.reset(); 00162 assert(!xmlc.nextSibling()); 00163 assert(false); 00164 } 00165 catch (ParseException& e) 00166 { 00167 } 00168 } 00169 00170 { 00171 cerr << "test childless root" << endl; 00172 Data contents("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 00173 "<foo> </foo>"); 00174 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00175 00176 assert(xmlc.getTag() == "foo"); 00177 cerr << "value: |" << xmlc.getValue() << "|" << endl; 00178 assert(xmlc.getValue().empty()); 00179 assert(xmlc.getAttributes().empty()); 00180 assert(xmlc.atRoot()); 00181 assert(!xmlc.atLeaf()); 00182 assert(!xmlc.parent()); 00183 assert(!xmlc.firstChild()); 00184 xmlc.reset(); 00185 assert(!xmlc.nextSibling()); 00186 } 00187 00188 { 00189 cerr << "test childless root with attributes" << endl; 00190 Data contents("<?xml version=\"1.0\"?><foo bar=\"baz\" attribute = 'value' ></foo>"); 00191 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00192 00193 assert(xmlc.getTag() == "foo"); 00194 assert(xmlc.getValue().empty()); 00195 resipCerr << Inserter(xmlc.getAttributes()) << endl; 00196 assert(xmlc.getAttributes().size() == 2); 00197 assert(xmlc.getAttributes().find("bar") != xmlc.getAttributes().end()); 00198 assert(xmlc.atRoot()); 00199 assert(!xmlc.atLeaf()); 00200 assert(!xmlc.parent()); 00201 assert(!xmlc.firstChild()); 00202 xmlc.reset(); 00203 assert(!xmlc.nextSibling()); 00204 } 00205 00206 { 00207 cerr << "test empty child" << endl; 00208 Data contents("<?xml version=\"1.0\"?><foo><child/></foo>"); 00209 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00210 00211 assert(xmlc.getTag() == "foo"); 00212 assert(xmlc.getValue().empty()); 00213 assert(xmlc.getAttributes().size() == 0); 00214 assert(xmlc.atRoot()); 00215 assert(!xmlc.atLeaf()); 00216 assert(!xmlc.parent()); 00217 00218 assert(xmlc.firstChild()); 00219 assert(xmlc.getTag() == "child"); 00220 assert(!xmlc.firstChild()); 00221 assert(!xmlc.nextSibling()); 00222 assert(xmlc.parent()); 00223 assert(xmlc.getTag() == "foo"); 00224 assert(xmlc.firstChild()); 00225 00226 xmlc.reset(); 00227 assert(xmlc.getTag() == "foo"); 00228 assert(!xmlc.nextSibling()); 00229 } 00230 00231 { 00232 cerr << "test contentless child" << endl; 00233 Data contents("<?xml version=\"1.0\"?> <foo><child></child></foo>"); 00234 XMLCursor xmlc(ParseBuffer(contents.data(), contents.size())); 00235 00236 assert(xmlc.getTag() == "foo"); 00237 assert(xmlc.getValue().empty()); 00238 assert(xmlc.getAttributes().size() == 0); 00239 assert(xmlc.atRoot()); 00240 assert(!xmlc.atLeaf()); 00241 assert(!xmlc.parent()); 00242 00243 assert(xmlc.firstChild()); 00244 assert(xmlc.getTag() == "child"); 00245 assert(!xmlc.firstChild()); 00246 assert(!xmlc.nextSibling()); 00247 assert(xmlc.parent()); 00248 assert(xmlc.getTag() == "foo"); 00249 assert(xmlc.firstChild()); 00250 assert(xmlc.parent()); 00251 assert(xmlc.getTag() == "foo"); 00252 assert(xmlc.firstChild()); 00253 00254 xmlc.reset(); 00255 assert(xmlc.getTag() == "foo"); 00256 assert(!xmlc.nextSibling()); 00257 } 00258 00259 { 00260 cerr << "test tree" << endl; 00261 Data contents("<?xml version=\"1.0\"?> \n" 00262 "<root>\n" 00263 " <P1>\n" 00264 " <A1></A1>\n" 00265 " <A2></A2>\n" 00266 " </P1>\n" 00267 " <P2>\n" 00268 " <B1></B1>\n" 00269 " <B2></B2>\n" 00270 " </P2>\n" 00271 " </root> "); 00272 00273 XMLCursor tree(ParseBuffer(contents.data(), contents.size())); 00274 00275 assert(tree.atRoot()); 00276 assert(tree.firstChild()); 00277 assert(tree.getTag() == "P1"); 00278 assert(tree.firstChild()); 00279 assert(tree.getTag() == "A1"); 00280 00281 assert(tree.parent()); 00282 assert(tree.getTag() == "P1"); 00283 assert(tree.firstChild()); 00284 00285 assert(tree.nextSibling()); 00286 assert(tree.getTag() == "A2"); 00287 assert(tree.parent()); 00288 assert(!tree.atRoot()); 00289 assert(tree.nextSibling()); 00290 assert(tree.getTag() == "P2"); 00291 assert(tree.firstChild()); 00292 assert(tree.getTag() == "B1"); 00293 assert(tree.nextSibling()); 00294 assert(tree.getTag() == "B2"); 00295 assert(!tree.nextSibling()); 00296 assert(tree.parent()); 00297 assert(!tree.nextSibling()); 00298 } 00299 00300 { 00301 cerr << "test leafy tree" << endl; 00302 Data contents("<?xml version=\"1.0\"?> <root>Pie<P1 attribute = \"value\">I<A1>wish</A1>I<A2>could</A2>recollect</P1>pi" 00303 "<P2>eureka<B1>cried</B1>the<B2>great</B2>professor</P2>christmas</root> "); 00304 XMLCursor tree(ParseBuffer(contents.data(), contents.size())); 00305 00306 assert(tree.firstChild()); 00307 assert(tree.atLeaf()); 00308 assert(tree.getTag().empty()); 00309 assert(tree.getValue() == "Pie"); 00310 assert(tree.nextSibling()); 00311 assert(tree.getTag() == "P1"); 00312 assert(tree.getAttributes().size() == 1); 00313 assert(tree.nextSibling()); 00314 assert(tree.getTag().empty()); 00315 assert(tree.getValue() == "pi"); 00316 assert(tree.nextSibling()); 00317 assert(tree.getTag() == "P2"); 00318 assert(tree.nextSibling()); 00319 assert(tree.getTag().empty()); 00320 assert(tree.getValue() == "christmas"); 00321 assert(!tree.nextSibling()); 00322 } 00323 00324 { 00325 cerr << "test CRLF canonicalization" << endl; 00326 00327 Data contents("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" 00328 "<list xmlns=\"urn:ietf:params:xml:ns:rmli\"\r\n" 00329 " uri=\"sip:adam-friends@pres.example.com\" version=\"2\"\r\n" 00330 " name=\"Buddy List at COM\" fullState=\"false\">\r\n" 00331 " <resource uri=\"sip:ed@example.net\" name=\"Ed at NET\">\r\n" 00332 " <instance id=\"sdlkmeopdf\" state=\"pending\"/>\r\n" 00333 " </resource>\r\n" 00334 " <resource uri=\"sip:adam-friends@example.org\"\r\n" 00335 " name=\"My Friends at ORG\">\r\n" 00336 " <instance id=\"cmpqweitlp\" state=\"active\"\r\n" 00337 " cid=\"1KQhyE@pres.example.com\"/>\r\n" 00338 " </resource>\r\n" 00339 "</list>"); 00340 00341 XMLCursor tree(ParseBuffer(contents.data(), contents.size())); 00342 00343 cerr << "root tag = |" << tree.getTag() << "|" << endl; 00344 assert(tree.getTag() == "list"); 00345 tree.firstChild(); 00346 do 00347 { 00348 cerr << tree.getTag() << endl; 00349 } 00350 while (tree.nextSibling()); 00351 00352 00353 assert(tree.getTag() == "resource"); 00354 } 00355 00356 cerr << "All OK" << endl; 00357 00358 return 0; 00359 } 00360 /* ==================================================================== 00361 * The Vovida Software License, Version 1.0 00362 * 00363 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00364 * 00365 * Redistribution and use in source and binary forms, with or without 00366 * modification, are permitted provided that the following conditions 00367 * are met: 00368 * 00369 * 1. Redistributions of source code must retain the above copyright 00370 * notice, this list of conditions and the following disclaimer. 00371 * 00372 * 2. Redistributions in binary form must reproduce the above copyright 00373 * notice, this list of conditions and the following disclaimer in 00374 * the documentation and/or other materials provided with the 00375 * distribution. 00376 * 00377 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00378 * and "Vovida Open Communication Application Library (VOCAL)" must 00379 * not be used to endorse or promote products derived from this 00380 * software without prior written permission. For written 00381 * permission, please contact vocal@vovida.org. 00382 * 00383 * 4. Products derived from this software may not be called "VOCAL", nor 00384 * may "VOCAL" appear in their name, without prior written 00385 * permission of Vovida Networks, Inc. 00386 * 00387 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00388 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00389 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00390 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00391 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00392 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00393 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00394 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00395 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00396 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00397 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00398 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00399 * DAMAGE. 00400 * 00401 * ==================================================================== 00402 * 00403 * This software consists of voluntary contributions made by Vovida 00404 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00405 * Inc. For more information on Vovida Networks, Inc., please see 00406 * <http://www.vovida.org/>. 00407 * 00408 */
1.7.5.1