reSIProcate/stack  9373
testXMLCursor.cxx
Go to the documentation of this file.
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  */