Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dom_document.cpp

Go to the documentation of this file.
00001 /*
00002 **  ClanLib SDK
00003 **  Copyright (c) 1997-2005 The ClanLib Team
00004 **
00005 **  This software is provided 'as-is', without any express or implied
00006 **  warranty.  In no event will the authors be held liable for any damages
00007 **  arising from the use of this software.
00008 **
00009 **  Permission is granted to anyone to use this software for any purpose,
00010 **  including commercial applications, and to alter it and redistribute it
00011 **  freely, subject to the following restrictions:
00012 **
00013 **  1. The origin of this software must not be misrepresented; you must not
00014 **     claim that you wrote the original software. If you use this software
00015 **     in a product, an acknowledgment in the product documentation would be
00016 **     appreciated but is not required.
00017 **  2. Altered source versions must be plainly marked as such, and must not be
00018 **     misrepresented as being the original software.
00019 **  3. This notice may not be removed or altered from any source distribution.
00020 **
00021 **  Note: Some of the libraries ClanLib link to may have additional
00022 **  requirements or restrictions.
00023 **
00024 **  File Author(s):
00025 **
00026 **    Magnus Norddahl
00027 */
00028 
00029 #include "precomp.h"
00030 #include "dom_document.h"
00031 #include "dom_document_type.h"
00032 #include "dom_implementation.h"
00033 #include "dom_element.h"
00034 #include "dom_document_fragment.h"
00035 #include "dom_text.h"
00036 #include "dom_comment.h"
00037 #include "dom_cdata_section.h"
00038 #include "dom_processing_instruction.h"
00039 #include "dom_attr.h"
00040 #include "dom_entity_reference.h"
00041 #include "dom_node_list.h"
00042 //#include "xml_tokenizer.h"
00043 //#include "xml_writer.h"
00044 //#include "xml_token.h"
00045 //#include "xml_token_load.h"
00046 //#include "xml_token_save.h"
00047 //#include "xml_token_string.h"
00048 #include "dom_document_generic.h"
00049 #include <stack>
00050 
00052 // CL_DomDocument construction:
00053 
00054 CL_DomDocument::CL_DomDocument() : CL_DomNode(CL_SharedPtr<CL_DomNode_Generic>(new CL_DomDocument_Generic))
00055 {
00056 }
00057 /*
00058 CL_DomDocument::CL_DomDocument(CL_IODevice *input, bool delete_input, bool eat_whitespace)
00059 : CL_DomNode(CL_SharedPtr<CL_DomNode_Generic>(new CL_DomDocument_Generic))
00060 {
00061         load(input, delete_input, eat_whitespace);
00062 }
00063 */
00064 CL_DomDocument::CL_DomDocument(const CL_SharedPtr<CL_DomNode_Generic> &impl) : CL_DomNode(impl)
00065 {
00066 }
00067 
00068 CL_DomDocument::~CL_DomDocument()
00069 {
00070 }
00071 
00073 // CL_DomDocument attributes:
00074 
00075 CL_DomDocumentType CL_DomDocument::get_doctype()
00076 {
00077         return CL_DomDocumentType(*this);
00078 }
00079 
00080 CL_DomImplementation CL_DomDocument::get_implementation()
00081 {
00082         return CL_DomImplementation(*this);
00083 }
00084 
00085 CL_DomElement CL_DomDocument::get_document_element()
00086 {
00087         CL_DomNode cur(impl->first_child);
00088         while (!cur.is_null())
00089         {
00090                 if (cur.is_element()) return cur.to_element();
00091                 cur = cur.get_next_sibling();
00092         }
00093         return CL_DomElement();
00094 }
00095 
00097 // CL_DomDocument operations:
00098 
00099 CL_DomElement CL_DomDocument::create_element(const std::string &tag_name)
00100 {
00101         return CL_DomElement(*this, tag_name);
00102 }
00103 
00104 CL_DomDocumentFragment CL_DomDocument::create_document_fragment()
00105 {
00106         return CL_DomDocumentFragment(*this);
00107 }
00108 
00109 CL_DomText CL_DomDocument::create_text_node(const std::string &data)
00110 {
00111         return CL_DomText(*this, data);
00112 }
00113 
00114 CL_DomComment CL_DomDocument::create_comment(const std::string &data)
00115 {
00116         return CL_DomComment(*this, data);
00117 }
00118 
00119 CL_DomCDATASection CL_DomDocument::create_cdata_section(const std::string &data)
00120 {
00121         return CL_DomCDATASection(*this, data);
00122 }
00123 
00124 CL_DomProcessingInstruction CL_DomDocument::create_processing_instruction(
00125         const std::string &target,
00126         const std::string &data)
00127 {
00128         return CL_DomProcessingInstruction(*this, target, data);
00129 }
00130 
00131 CL_DomAttr CL_DomDocument::create_attribute(const std::string &name)
00132 {
00133         return CL_DomAttr(*this, name);
00134 }
00135 
00136 CL_DomEntityReference CL_DomDocument::create_entity_reference(const std::string &name)
00137 {
00138         return CL_DomEntityReference(*this, name);
00139 }
00140 
00141 CL_DomNodeList CL_DomDocument::get_elements_by_tag_name(const std::string &tag_name)
00142 {
00143         return CL_DomNodeList(*this, tag_name);
00144 }
00145 /*
00146 std::vector<CL_DomNode> CL_DomDocument::load(
00147         CL_IODevice *input,
00148         bool delete_input,
00149         bool eat_whitespace,
00150         CL_DomNode insert_point)
00151 {
00152         clear_all();
00153 
00154         CL_XMLTokenizer tokenizer(input, delete_input);
00155         tokenizer.set_eat_whitespace(eat_whitespace);
00156 
00157         if (insert_point.is_element() == false)
00158                 insert_point = *this;
00159                 
00160         std::stack<CL_DomNode> node_stack;
00161         node_stack.push(insert_point);
00162 
00163         std::vector<CL_DomNode> result;
00164         
00165         try
00166         {
00167                 CL_XMLTokenLoad cur_token = tokenizer.next();
00168                 while (cur_token.get_type() != CL_XMLToken::NULL_TOKEN)
00169                 {
00170                         switch (cur_token.get_type())
00171                         {
00172                         case CL_XMLToken::TEXT_TOKEN:
00173                                 node_stack.top().append_child(create_text_node(cur_token.get_value()));
00174                                 if (node_stack.top() == insert_point)
00175                                         result.push_back(node_stack.top().get_last_child());
00176                                 break;
00177 
00178                         case CL_XMLToken::CDATA_SECTION_TOKEN:
00179                                 node_stack.top().append_child(create_cdata_section(cur_token.get_value()));
00180                                 if (node_stack.top() == insert_point)
00181                                         result.push_back(node_stack.top().get_last_child());
00182                                 break;
00183 
00184                         case CL_XMLToken::ELEMENT_TOKEN:
00185                                 if (cur_token.get_variant() != CL_XMLToken::END)
00186                                 {
00187                                         CL_DomElement element = create_element(cur_token.get_name());
00188                                         node_stack.top().append_child(element);
00189                                         if (node_stack.top() == insert_point)
00190                                                 result.push_back(node_stack.top().get_last_child());
00191 
00192                                         int size = cur_token.get_attributes_number();
00193                                         for (int i=0; i<size; i++)
00194                                         {
00195                                                 std::pair<CL_XMLTokenString, CL_XMLTokenString> const & attribute = cur_token.get_attribute_fast(i);
00196                                                 element.set_attribute(attribute.first.to_string(), attribute.second.to_string());
00197                                         }
00198                                 
00199                                         if (cur_token.get_variant() == CL_XMLToken::BEGIN)
00200                                                 node_stack.push(element);
00201                                 }
00202                                 else
00203                                 {
00204                                         node_stack.pop();
00205                                         if (node_stack.empty()) throw CL_Error("Malformed XML tree!");
00206                                 }
00207                                 break;
00208 
00209                         case CL_XMLToken::NULL_TOKEN: 
00210                                 break;
00211 
00212                         case CL_XMLToken::ENTITY_REFERENCE_TOKEN: 
00213                                 break;
00214 
00215                         case CL_XMLToken::ENTITY_TOKEN: 
00216                                 break;
00217                         
00218                         case CL_XMLToken::COMMENT_TOKEN:
00219                                 break;
00220 
00221                         case CL_XMLToken::DOCUMENT_TYPE_TOKEN:
00222                                 break;
00223 
00224                         case CL_XMLToken::NOTATION_TOKEN:
00225                                 break;
00226 
00227                         case CL_XMLToken::PROCESSING_INSTRUCTION_TOKEN:
00228                                 break;
00229                         }               
00230 
00231                         cur_token = tokenizer.next();
00232                 }
00233         }
00234         catch (CL_Error e)
00235         {
00236                 for (std::vector<CL_DomNode>::size_type i = 0; i < result.size(); i++)
00237                 {
00238                         insert_point.remove_child(result[i]);
00239                 }
00240                 throw e;
00241         }
00242         return result;
00243 }
00244 
00245 void CL_DomDocument::save(CL_IODevice *output, bool delete_output, bool insert_whitespace)
00246 {
00247         CL_XMLWriter writer(output, delete_output);
00248         writer.set_insert_whitespace(insert_whitespace);
00249 
00250         std::stack<CL_DomNode> node_stack;
00251         CL_DomNode cur_node = get_first_child();
00252         while (!cur_node.is_null())
00253         {
00254                 // Create opening node:
00255                 CL_XMLTokenSave opening_node;
00256                 opening_node.set_type((CL_XMLToken::TokenType) cur_node.get_node_type());
00257                 opening_node.set_variant(cur_node.has_child_nodes() ? CL_XMLToken::BEGIN : CL_XMLToken::SINGLE);
00258                 opening_node.set_name(cur_node.get_node_name());
00259                 opening_node.set_value(cur_node.get_node_value());
00260                 if (cur_node.is_element())
00261                 {
00262                         for (int i = 0; i < cur_node.impl->attributes.get_length(); ++i)
00263                         {
00264                                 opening_node.set_attribute(cur_node.impl->attributes.item(i).to_attr().get_name(),
00265                                                                                                         cur_node.impl->attributes.item(i).to_attr().get_value());
00266                         }
00267                 }
00268                 writer.write(opening_node);
00269 
00270                 // Create any possible child nodes:
00271                 if (cur_node.has_child_nodes())
00272                 {
00273                         node_stack.push(cur_node);
00274                         cur_node = cur_node.get_first_child();
00275                         continue;
00276                 }
00277 
00278                 // Create closing nodes until we reach next opening node in tree:
00279                 while (true)
00280                 {
00281                         if (cur_node.has_child_nodes())
00282                         {
00283                                 CL_XMLTokenSave closing_node;
00284                                 closing_node.set_type((CL_XMLToken::TokenType) cur_node.get_node_type());
00285                                 closing_node.set_name(cur_node.get_node_name());
00286                                 closing_node.set_variant(CL_XMLToken::END);
00287                                 writer.write(closing_node);
00288                         }
00289 
00290                         cur_node = cur_node.get_next_sibling();
00291                         if (!cur_node.is_null()) break;
00292                         if (node_stack.empty()) break;
00293 
00294                         cur_node = node_stack.top();
00295                         node_stack.pop();
00296                 }
00297         }
00298 }
00299 */
00300 void CL_DomDocument::clear_all()
00301 {
00302         while (!get_first_child().is_null())
00303         {
00304                 CL_DomNode node = get_first_child();
00305                 remove_child(node);
00306         }
00307 }
00308 
00310 // CL_DomDocument implementation:

Generated on Sat Feb 19 22:51:15 2005 for npcore by  doxygen 1.4.1