/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* .
*/
//
// Various DOM tests.
// Contents include
// 1. NodeIterator tests
// 2. Tree Walker tests
// All individual are wrapped in a memory leak checker.
//
// This is NOT a complete test of DOM functionality.
//
/**
* $Log: Traversal.cpp,v $
* Revision 1.6 2002/03/07 21:42:14 peiyongz
* Call Terminate() to avoid memory tools reporting memory leak
*
* Revision 1.5 2002/02/04 20:12:43 tng
* Test DOM Level missing functions:
* 1. NodeIterator::getRoot
* 2. TreeWalker::getRoot
*
* Revision 1.4 2002/02/01 22:43:48 peiyongz
* sane_include
*
* Revision 1.3 2001/11/23 16:18:54 tng
* Elimiate compiler warning: Warning: String literal converted to char* in formal argument file in call to tassert(bool, char*, int).
*
* Revision 1.2 2000/03/11 03:19:57 chchou
* Fix bug # 19, add const keyword to API.
* As a result, update test case.
*
* Revision 1.1 2000/02/18 23:01:01 abagchi
* Initial checkin
*
* Revision 1.2 2000/02/15 00:59:58 aruna1
* Previous node iterator related changes in.
*
* Revision 1.1 2000/02/08 02:08:58 aruna1
* DOM NodeIterator and TreeWalker tests initial check in
*
*/
#include
#include
#include
#include
#include
#include
#include
#define TASSERT(c) tassert((c), __FILE__, __LINE__)
void tassert(bool c, const char *file, int line)
{
if (!c)
printf("Failure. Line %d, file %s\n", line, file);
};
#define TESTPROLOG entryMemState = DomMemDebug();
#define TESTEPILOG exitMemState = DomMemDebug(); \
if (entryMemState != exitMemState) { \
printf(" Memory leak at line %d, file %s: ", __LINE__, __FILE__); \
exitMemState.printDifference(entryMemState); \
}
#define EXCEPTION_TEST(operation, expected_exception) \
{ \
try { \
operation; \
printf(" Error: no exception thrown at line %d\n", __LINE__); \
} \
catch (DOM_DOMException &e) { \
if (e.code != expected_exception) \
printf(" Wrong exception code: %d at line %d\n", e.code, __LINE__); \
} \
catch (...) { \
printf(" Wrong exception thrown at line %d\n", __LINE__); \
} \
}
class MyFilter : public DOM_NodeFilter {
public:
MyFilter(short nodeType, bool reject=false) : DOM_NodeFilter(), fNodeType(nodeType), fReject(reject) {};
virtual short acceptNode(const DOM_Node &node) const;
private:
short fNodeType;
bool fReject;
};
/*
Node Types can be of the following:
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_NODE = 4,
ENTITY_REFERENCE_NODE = 5,
ENTITY_NODE = 6,
PROCESSING_INSTRUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_NODE = 10,
DOCUMENT_FRAGMENT_NODE = 11,
NOTATION_NODE = 12
*/
short MyFilter::acceptNode(const DOM_Node &node) const {
if (fNodeType == 0)
return DOM_NodeFilter::FILTER_ACCEPT;
if (node.getNodeType() == fNodeType) {
return DOM_NodeFilter::FILTER_ACCEPT;
} else {
return fReject ? DOM_NodeFilter::FILTER_REJECT : DOM_NodeFilter::FILTER_SKIP;
}
}
int main()
{
DomMemDebug entryMemState, exitMemState;
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
char *pMessage = XMLString::transcode(toCatch.getMessage());
fprintf(stderr, "Error during XMLPlatformUtils::Initialize(). \n"
" Message is: %s\n", pMessage);
delete [] pMessage;
return -1;
}
//
// Doc - Create a small document tree
//
{
//creating a DOM Tree
/* Tests are based on the tree structure below
doc - root - E11 (attr01) - textNode1
- E111
- E112
- cdataSec
- E12 (attr02) - textNode2
- E121
- E122
- E13 - E131
- docPI
- comment
*/
DOM_Document doc = DOM_Document::createDocument();
//Creating a root element
DOM_Element root = doc.createElement("RootElement");
doc.appendChild(root);
//Creating the siblings of root
DOM_Element E11 = doc.createElement("FirstSibling");
root.appendChild(E11);
DOM_Element E12 = doc.createElement("SecondSibling");
root.appendChild(E12);
DOM_Element E13 = doc.createElement("ThirdSibling");
root.appendChild(E13);
//Attaching texts to few siblings
DOM_Text textNode1 = doc.createTextNode("Text1");
E11.appendChild(textNode1);
DOM_Text textNode2 = doc.createTextNode("Text2");
E12.appendChild(textNode2);
//creating child of siblings
DOM_Element E111 = doc.createElement("FirstSiblingChild1");
E11.appendChild(E111);
DOM_Attr attr01 = doc.createAttribute("Attr01");
E11.setAttributeNode(attr01);
DOM_Element E112 = doc.createElement("FirstSiblingChild2");
E11.appendChild(E112);
DOM_Element E121 = doc.createElement("SecondSiblingChild1");
E12.appendChild(E121);
DOM_Attr attr02 = doc.createAttribute("Attr01");
E12.setAttributeNode(attr02);
DOM_Element E122 = doc.createElement("SecondSiblingChild2");
E12.appendChild(E122);
DOM_Element E131 = doc.createElement("ThirdSiblingChild1");
E13.appendChild(E131);
DOM_Comment comment = doc.createComment("DocComment");
root.appendChild(comment);
DOM_CDATASection cdataSec = doc.createCDATASection("DocCDataSection");
E11.appendChild(cdataSec);
DOM_ProcessingInstruction docPI = doc.createProcessingInstruction("DocPI", "DocTarget");
E13.appendChild(docPI);
/*
following are whatToShow types:
SHOW_ALL = 0x0000FFFF,
SHOW_ELEMENT = 0x00000001,
SHOW_ATTRIBUTE = 0x00000002,
SHOW_TEXT = 0x00000004,
SHOW_CDATA_SECTION = 0x00000008,
SHOW_ENTITY_REFERENCE = 0x00000010,
SHOW_ENTITY = 0x00000020,
SHOW_PROCESSING_INSTRUCTION = 0x00000040,
SHOW_COMMENT = 0x00000080,
SHOW_DOCUMENT = 0x00000100,
SHOW_DOCUMENT_TYPE = 0x00000200,
SHOW_DOCUMENT_FRAGMENT = 0x00000400,
SHOW_NOTATION = 0x00000800
*/
////////// NodeIterator Test Cases ////////////////
TESTPROLOG;
{
// all node iterating test
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_ALL;
MyFilter* filter = new MyFilter(0);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 65535);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT (nd ==root);
nd = iter.nextNode();
TASSERT (nd ==E11);
nd = iter.nextNode();
TASSERT(nd == textNode1);
nd = iter.nextNode();
TASSERT(nd == E111);
nd = iter.nextNode();
TASSERT(nd == E112);
nd = iter.nextNode();
TASSERT(nd == cdataSec);
nd = iter.nextNode();
TASSERT(nd == E12);
nd = iter.nextNode();
TASSERT(nd == textNode2);
nd = iter.nextNode();
TASSERT(nd == E121);
nd = iter.nextNode();
TASSERT(nd == E122);
nd = iter.nextNode();
TASSERT(nd == E13);
nd = iter.nextNode();
TASSERT(nd == E131);
nd = iter.nextNode();
TASSERT(nd == docPI);
nd = iter.nextNode();
TASSERT(nd == comment);
nd = iter.previousNode();
TASSERT(nd == comment);
nd = iter.previousNode();
TASSERT(nd == docPI);
nd = iter.previousNode();
TASSERT(nd == E131);
//test getRoot
TASSERT(iter.getRoot() == root);
TASSERT(iter.getRoot() != doc);
delete filter;
}
TESTEPILOG;
TESTPROLOG;
{
//element node iterating test
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_ELEMENT;
MyFilter* filter = new MyFilter(DOM_Node::ELEMENT_NODE);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 1);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT (nd ==root);
nd = iter.nextNode();
TASSERT (nd ==E11);
nd = iter.nextNode();
TASSERT(nd == E111);
nd = iter.nextNode();
TASSERT(nd == E112);
nd = iter.nextNode();
TASSERT(nd == E12);
nd = iter.nextNode();
TASSERT(nd == E121);
nd = iter.nextNode();
TASSERT(nd == E122);
nd = iter.nextNode();
TASSERT(nd == E13);
nd = iter.nextNode();
TASSERT(nd == E131);
nd = iter.previousNode();
TASSERT(nd == E131);
nd = iter.previousNode();
TASSERT(nd == E13);
nd = iter.previousNode();
TASSERT(nd == E122);
delete filter;
}
TESTEPILOG;
TESTPROLOG;
{
// Text node iterating test
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_TEXT;
MyFilter* filter = new MyFilter(DOM_Node::TEXT_NODE);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 4);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT (nd ==textNode1);
nd = iter.nextNode();
TASSERT (nd ==textNode2);
nd = iter.previousNode();
TASSERT(nd == textNode2);
delete filter;
}
TESTEPILOG;
TESTPROLOG;
{
//CDataSection node itearating test
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_CDATA_SECTION;
MyFilter* filter = new MyFilter(DOM_Node::CDATA_SECTION_NODE);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 8);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT(nd == cdataSec);
nd = iter.nextNode();
TASSERT(nd == 0);
delete filter;
}
TESTEPILOG;
TESTPROLOG;
{
// PI nodes iterating test
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_PROCESSING_INSTRUCTION;
MyFilter* filter = new MyFilter(DOM_Node::PROCESSING_INSTRUCTION_NODE);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 64);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT(nd == docPI);
nd = iter.nextNode();
TASSERT(nd == 0);
delete filter;
}
TESTEPILOG;
TESTPROLOG;
{
DOM_Node node = doc.getFirstChild();
unsigned long whatToShow = DOM_NodeFilter::SHOW_COMMENT;
MyFilter* filter = new MyFilter(DOM_Node::COMMENT_NODE);
DOM_NodeIterator iter = doc.createNodeIterator(root, whatToShow, filter, true);
TASSERT(iter.getWhatToShow() == 128);
TASSERT(iter.getExpandEntityReferences() == 1);
DOM_Node nd;
nd = iter.nextNode();
TASSERT(nd == comment);
nd = iter.nextNode();
TASSERT(nd == 0);
delete filter;
}
TESTEPILOG;
////////// TreeWalker Test Cases ////////////////
TESTPROLOG;
{
unsigned long whatToShow = DOM_NodeFilter::SHOW_ALL;
DOM_TreeWalker tw = doc.createTreeWalker(doc, whatToShow, 0, true);
TASSERT(tw.getCurrentNode() == doc);
TASSERT(tw.firstChild() == root);
TASSERT(tw.nextSibling() == 0);
TASSERT(tw.lastChild() == comment);
TASSERT(tw.firstChild() == 0);
TASSERT(tw.lastChild() == 0);
TASSERT(tw.nextSibling() == 0);
TASSERT(tw.nextNode() == 0);
TASSERT(tw.previousSibling() == E13);
TASSERT(tw.previousNode() == E122);
TASSERT(tw.parentNode() == E12);
TASSERT(tw.firstChild() == textNode2);
TASSERT(tw.previousSibling() == 0);
TASSERT(tw.nextSibling() == E121);
TASSERT(tw.nextNode() == E122);
TASSERT(tw.parentNode() == E12);
TASSERT(tw.previousSibling() == E11);
TASSERT(tw.previousNode() == root);
TASSERT(tw.previousNode() == doc);
TASSERT(tw.previousNode() == 0);
TASSERT(tw.parentNode() == 0);
TASSERT(tw.getCurrentNode() == doc);
}
TESTEPILOG;
TESTPROLOG;
{
MyFilter mf(DOM_Node::ELEMENT_NODE);
unsigned long whatToShow = DOM_NodeFilter::SHOW_ALL;
DOM_TreeWalker tw = doc.createTreeWalker(root, whatToShow, &mf, true);
TASSERT(tw.getCurrentNode() == root);
TASSERT(tw.parentNode() == 0); //should not change currentNode
TASSERT(tw.getCurrentNode() == root);
TASSERT(tw.nextNode() == E11);
TASSERT(tw.nextNode() == E111);
tw.setCurrentNode(E12);
//when first is not visible, should it go to its sibling?
TASSERT(tw.firstChild() == E121); //first visible child
TASSERT(tw.previousSibling() == 0);
}
TESTEPILOG;
TESTPROLOG;
{
MyFilter mf(DOM_Node::ELEMENT_NODE, true);
unsigned long whatToShow = DOM_NodeFilter::SHOW_ELEMENT;
DOM_TreeWalker tw = doc.createTreeWalker(root, whatToShow, &mf, true);
tw.setCurrentNode(E12);
TASSERT(tw.firstChild() == E121); //still first visible child
}
TESTEPILOG;
TESTPROLOG;
{
MyFilter mf(DOM_Node::TEXT_NODE);
unsigned long whatToShow = DOM_NodeFilter::SHOW_TEXT;
DOM_TreeWalker tw = doc.createTreeWalker(root, whatToShow, &mf, true);
//when first is not visible, should it go to its descendent?
TASSERT(tw.firstChild() == textNode1); //E11 skipped
TASSERT(tw.firstChild() == 0);
TASSERT(tw.nextNode() == textNode2);
TASSERT(tw.nextSibling() == 0);
TASSERT(tw.parentNode() == 0); //no visible ancestor
TASSERT(tw.getCurrentNode() == textNode2);
tw.setCurrentNode(root);
//when last is not visible, should it go to its sibling & descendent?
TASSERT(tw.lastChild() == textNode2); //last visible child
tw.setCurrentNode(E12);
//when next sibling is not visible, should it go to its descendent?
TASSERT(tw.nextSibling() == 0);
}
TESTEPILOG;
TESTPROLOG;
{
MyFilter mf(DOM_Node::TEXT_NODE, true);
unsigned long whatToShow = DOM_NodeFilter::SHOW_TEXT;
DOM_TreeWalker tw = doc.createTreeWalker(root, whatToShow, &mf, true);
TASSERT(tw.firstChild() == 0); //E11 rejected and no children is TEXT
TASSERT(tw.getCurrentNode() == root);
TASSERT(tw.nextNode() == 0); //E11 rejected so can't get to textNode1
//test getRoot
TASSERT(tw.getRoot() == root);
TASSERT(tw.getRoot() != doc);
}
TESTEPILOG;
};
//
// Print Final allocation stats for full test
//
DomMemDebug().print();
// And call the termination method
XMLPlatformUtils::Terminate();
return 0;
};