00001 /* 00002 * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org) 00003 * All Rights Reserved 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in 00013 * the documentation and/or other materials provided with the 00014 * distribution. 00015 * 3. Neither the name of the Author nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00021 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00022 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 00023 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00026 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00027 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00028 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00029 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00030 * SUCH DAMAGE. 00031 */ 00032 00033 /** @file 00034 * This file contains the definition of the xml::document class. 00035 **/ 00036 00037 #ifndef _xmlwrapp_document_h_ 00038 #define _xmlwrapp_document_h_ 00039 00040 // xmlwrapp includes 00041 #include <xmlwrapp/node.h> 00042 00043 // standard includes 00044 #include <iosfwd> 00045 #include <string> 00046 #include <cstddef> 00047 00048 // forward declaration 00049 namespace xslt { class stylesheet; } 00050 00051 namespace xml { 00052 00053 // forward declarations 00054 class tree_parser; 00055 struct doc_impl; 00056 00057 /** 00058 * The xml::document class is used to hold the XML tree and various bits of 00059 * information about it. 00060 **/ 00061 class document { 00062 public: 00063 /// size type 00064 typedef std::size_t size_type; 00065 00066 //#################################################################### 00067 /** 00068 * Create a new XML document with the default settings. The new document 00069 * will contain a root node with a name of "blank". 00070 * 00071 * @author Peter Jones 00072 **/ 00073 //#################################################################### 00074 document (void); 00075 00076 //#################################################################### 00077 /** 00078 * Create a new XML document and set the name of the root element to the 00079 * given text. 00080 * 00081 * @param root_name What to set the name of the root element to. 00082 * @author Peter Jones 00083 **/ 00084 //#################################################################### 00085 explicit document (const char *root_name); 00086 00087 //#################################################################### 00088 /** 00089 * Create a new XML document and set the root node. 00090 * 00091 * @param n The node to use as the root node. n will be copied. 00092 * @author Peter Jones 00093 **/ 00094 //#################################################################### 00095 explicit document (const node &n); 00096 00097 //#################################################################### 00098 /** 00099 * Copy construct a new XML document. The new document will be an exact 00100 * copy of the original. 00101 * 00102 * @param other The other document object to copy from. 00103 * @author Peter Jones 00104 **/ 00105 //#################################################################### 00106 document (const document &other); 00107 00108 //#################################################################### 00109 /** 00110 * Copy another document object into this one using the assignment 00111 * operator. This document object will be an exact copy of the other 00112 * document after the assignement. 00113 * 00114 * @param other The document to copy from. 00115 * @return *this. 00116 * @author Peter Jones 00117 **/ 00118 //#################################################################### 00119 document& operator= (const document &other); 00120 00121 //#################################################################### 00122 /** 00123 * Swap one xml::document object for another. 00124 * 00125 * @param other The other document to swap 00126 * @author Peter Jones 00127 **/ 00128 //#################################################################### 00129 void swap (document &other); 00130 00131 //#################################################################### 00132 /** 00133 * Clean up after an XML document object. 00134 * 00135 * @author Peter Jones 00136 **/ 00137 //#################################################################### 00138 ~document (void); 00139 00140 //#################################################################### 00141 /** 00142 * Get a reference to the root node of this document. If no root node 00143 * has been set, the returned node will be a blank node. You should take 00144 * caution to use a reference so that you don't copy the whole node 00145 * tree! 00146 * 00147 * @return A const reference to the root node. 00148 * @author Peter Jones 00149 **/ 00150 //#################################################################### 00151 const node& get_root_node (void) const; 00152 00153 //#################################################################### 00154 /** 00155 * Get a reference to the root node of this document. If no root node 00156 * has been set, the returned node will be a blank node. You should take 00157 * caution to use a reference so that you don't copy the whole node 00158 * tree! 00159 * 00160 * @return A reference to the root node. 00161 * @author Peter Jones 00162 **/ 00163 //#################################################################### 00164 node& get_root_node (void); 00165 00166 //#################################################################### 00167 /** 00168 * Set the root node to the given node. A full copy is made and stored 00169 * in the document object. 00170 * 00171 * @param n The new root node to use. 00172 * @author Peter Jones 00173 **/ 00174 //#################################################################### 00175 void set_root_node (const node &n); 00176 00177 //#################################################################### 00178 /** 00179 * Get the XML version for this document. For generated documents, the 00180 * version will be the default. For parsed documents, this will be the 00181 * version from the XML processing instruction. 00182 * 00183 * @return The XML version string for this document. 00184 * @author Peter Jones 00185 **/ 00186 //#################################################################### 00187 const std::string& get_version (void) const; 00188 00189 //#################################################################### 00190 /** 00191 * Set the XML version number for this document. This version string 00192 * will be used when generating the XML output. 00193 * 00194 * @param version The version string to use, like "1.0". 00195 * @author Peter Jones 00196 **/ 00197 //#################################################################### 00198 void set_version (const char *version); 00199 00200 //#################################################################### 00201 /** 00202 * Get the XML encoding for this document. The default encoding is 00203 * ISO-8859-1. 00204 * 00205 * @return The encoding string. 00206 * @author Peter Jones 00207 **/ 00208 //#################################################################### 00209 const std::string& get_encoding (void) const; 00210 00211 //#################################################################### 00212 /** 00213 * Set the XML encoding string. If you don't set this, it will default 00214 * to ISO-8859-1. 00215 * 00216 * @param encoding The XML encoding to use. 00217 * @author Peter Jones 00218 * @author Dmitriy Nikitinskiy 00219 **/ 00220 //#################################################################### 00221 void set_encoding (const char *encoding); 00222 00223 //#################################################################### 00224 /** 00225 * Find out if the current document is a standalone document. For 00226 * generated documents, this will be the default. For parsed documents 00227 * this will be set based on the XML processing instruction. 00228 * 00229 * @return True if this document is standalone. 00230 * @return False if this document is not standalone. 00231 * @author Peter Jones 00232 **/ 00233 //#################################################################### 00234 bool get_is_standalone (void) const; 00235 00236 //#################################################################### 00237 /** 00238 * Set the standalone flag. This will show up in the XML output in the 00239 * correct processing instruction. 00240 * 00241 * @param sa What to set the standalone flag to. 00242 * @author Peter Jones 00243 **/ 00244 //#################################################################### 00245 void set_is_standalone (bool sa); 00246 00247 //#################################################################### 00248 /** 00249 * Walk through the document and expand <xi:include> elements. For more 00250 * information, please see the w3c recomendation for XInclude. 00251 * http://www.w3.org/2001/XInclude. 00252 * 00253 * The return value of this function may change to int after a bug has 00254 * been fixed in libxml2 (xmlXIncludeDoProcess). 00255 * 00256 * @return False if there was an error with substitutions. 00257 * @return True if there were no errors (with or without substitutions). 00258 * @author Peter Jones 00259 * @author Daniel Evison 00260 **/ 00261 //#################################################################### 00262 bool process_xinclude (void); 00263 00264 //#################################################################### 00265 /** 00266 * Test to see if this document has an internal subset. That is, DTD 00267 * data that is declared within the XML document itself. 00268 * 00269 * @return True if this document has an internal subset. 00270 * @return False otherwise. 00271 * @author Peter Jones 00272 **/ 00273 //#################################################################### 00274 bool has_internal_subset (void) const; 00275 00276 //#################################################################### 00277 /** 00278 * Test to see if this document has an external subset. That is, it 00279 * references a DTD from an external source, such as a file or URL. 00280 * 00281 * @return True if this document has an external subset. 00282 * @return False otherwise. 00283 * @author Peter Jones 00284 **/ 00285 //#################################################################### 00286 bool has_external_subset (void) const; 00287 00288 //#################################################################### 00289 /** 00290 * Validate this document against the DTD that has been attached to it. 00291 * This would happen at parse time if there was a !DOCTYPE definition. 00292 * If the DTD is valid, and the document is valid, this member function 00293 * will return true. 00294 * 00295 * If it returns false, you may want to send the document through 00296 * xmllint to get the actual error messages. 00297 * 00298 * @return True if the document is valid. 00299 * @return False if there was a problem with the DTD or XML doc. 00300 * @author Peter Jones 00301 **/ 00302 //#################################################################### 00303 bool validate (void); 00304 00305 //#################################################################### 00306 /** 00307 * Parse the given DTD and try to validate this document against it. If 00308 * the DTD is valid, and the document is valid, this member function 00309 * will return true. 00310 * 00311 * If it returns false, you may want to send the document through 00312 * xmllint to get the actual error messages. 00313 * 00314 * This member function will add the parsed DTD to this document as the 00315 * external subset after the validation. If there is already an external 00316 * DTD attached to this document it will be removed and deleted. 00317 * 00318 * @param dtdname A filename or URL for the DTD to use. 00319 * @return True if the document is valid. 00320 * @return False if there was a problem with the DTD or XML doc. 00321 * @author Peter Jones 00322 **/ 00323 //#################################################################### 00324 bool validate (const char *dtdname); 00325 00326 //#################################################################### 00327 /** 00328 * Returns the number of child nodes of this document. This will always 00329 * be at least one, since all xmlwrapp documents must have a root node. 00330 * This member function is useful to find out how many document children 00331 * there are, including processing instructions, comments, etc. 00332 * 00333 * @return The number of children nodes that this document has. 00334 * @author Peter Jones 00335 **/ 00336 //#################################################################### 00337 size_type size (void) const; 00338 00339 //#################################################################### 00340 /** 00341 * Get an iterator to the first child node of this document. If what you 00342 * really wanted was the root node (the first element) you should use 00343 * the get_root_node() member function instead. 00344 * 00345 * @return A xml::node::iterator that points to the first child node. 00346 * @return An end iterator if there are no children in this document 00347 * @author Peter Jones 00348 **/ 00349 //#################################################################### 00350 node::iterator begin (void); 00351 00352 //#################################################################### 00353 /** 00354 * Get a const_iterator to the first child node of this document. If 00355 * what you really wanted was the root node (the first element) you 00356 * should use the get_root_node() member function instead. 00357 * 00358 * @return A xml::node::const_iterator that points to the first child node. 00359 * @return An end const_iterator if there are no children in this document. 00360 * @author Peter Jones 00361 **/ 00362 //#################################################################### 00363 node::const_iterator begin (void) const; 00364 00365 //#################################################################### 00366 /** 00367 * Get an iterator that points one past the last child node for this 00368 * document. 00369 * 00370 * @return An end xml::node::iterator. 00371 * @author Peter Jones 00372 **/ 00373 //#################################################################### 00374 node::iterator end (void); 00375 00376 //#################################################################### 00377 /** 00378 * Get a const_iterator that points one past the last child node for 00379 * this document. 00380 * 00381 * @return An end xml::node::const_iterator. 00382 * @author Peter Jones 00383 **/ 00384 //#################################################################### 00385 node::const_iterator end (void) const; 00386 00387 //#################################################################### 00388 /** 00389 * Add a child xml::node to this document. You should not add a element 00390 * type node, since there can only be one root node. This member 00391 * function is only useful for adding processing instructions, comments, 00392 * etc.. If you do try to add a node of type element, an exception will 00393 * be thrown. 00394 * 00395 * @param child The child xml::node to add. 00396 * @author Peter Jones 00397 **/ 00398 //#################################################################### 00399 void push_back (const node &child); 00400 00401 //#################################################################### 00402 /** 00403 * Insert a new child node. The new node will be inserted at the end of 00404 * the child list. This is similar to the xml::node::push_back member 00405 * function except that an iterator to the inserted node is returned. 00406 * 00407 * The rules from the push_back member function apply here. Don't add a 00408 * node of type element. 00409 * 00410 * @param n The node to insert as a child of this document. 00411 * @return An iterator that points to the newly inserted node. 00412 * @see xml::document::push_back 00413 * @author Peter Jones 00414 **/ 00415 //#################################################################### 00416 node::iterator insert (const node &n); 00417 00418 //#################################################################### 00419 /** 00420 * Insert a new child node. The new node will be inserted before the 00421 * node pointed to by the given iterator. 00422 * 00423 * The rules from the push_back member function apply here. Don't add a 00424 * node of type element. 00425 * 00426 * @param position An iterator that points to the location where the new node should be inserted (before it). 00427 * @param n The node to insert as a child of this document. 00428 * @return An iterator that points to the newly inserted node. 00429 * @see xml::document::push_back 00430 * @author Peter Jones 00431 **/ 00432 //#################################################################### 00433 node::iterator insert (node::iterator position, const node &n); 00434 00435 //#################################################################### 00436 /** 00437 * Replace the node pointed to by the given iterator with another node. 00438 * The old node will be removed, including all its children, and 00439 * replaced with the new node. This will invalidate any iterators that 00440 * point to the node to be replaced, or any pointers or references to 00441 * that node. 00442 * 00443 * Do not replace this root node with this member function. The same 00444 * rules that apply to push_back apply here. If you try to replace a 00445 * node of type element, an exception will be thrown. 00446 * 00447 * @param old_node An iterator that points to the node that should be removed. 00448 * @param new_node The node to put in old_node's place. 00449 * @return An iterator that points to the new node. 00450 * @see xml::document::push_back 00451 * @author Peter Jones 00452 **/ 00453 //#################################################################### 00454 node::iterator replace (node::iterator old_node, const node &new_node); 00455 00456 //#################################################################### 00457 /** 00458 * Erase the node that is pointed to by the given iterator. The node 00459 * and all its children will be removed from this node. This will 00460 * invalidate any iterators that point to the node to be erased, or any 00461 * pointers or references to that node. 00462 * 00463 * Do not remove the root node using this member function. The same 00464 * rules that apply to push_back apply here. If you try to erase the 00465 * root node, an exception will be thrown. 00466 * 00467 * @param to_erase An iterator that points to the node to be erased. 00468 * @return An iterator that points to the node after the one being erased. 00469 * @see xml::document::push_back 00470 * @author Peter Jones 00471 **/ 00472 //#################################################################### 00473 node::iterator erase (node::iterator to_erase); 00474 00475 //#################################################################### 00476 /** 00477 * Erase all nodes in the given range, from frist to last. This will 00478 * invalidate any iterators that point to the nodes to be erased, or any 00479 * pointers or references to those nodes. 00480 * 00481 * Do not remove the root node using this member function. The same 00482 * rules that apply to push_back apply here. If you try to erase the 00483 * root node, an exception will be thrown. 00484 * 00485 * @param first The first node in the range to be removed. 00486 * @param last An iterator that points one past the last node to erase. Think xml::node::end(). 00487 * @return An iterator that points to the node after the last one being erased. 00488 * @see xml::document::push_back 00489 * @author Peter Jones 00490 **/ 00491 //#################################################################### 00492 node::iterator erase (node::iterator first, node::iterator last); 00493 00494 //#################################################################### 00495 /** 00496 * Convert the XML document tree into XML text data and place it into 00497 * the given string. 00498 * 00499 * @param s The string to place the XML text data. 00500 * @author Peter Jones 00501 **/ 00502 //#################################################################### 00503 void save_to_string (std::string &s) const; 00504 00505 //#################################################################### 00506 /** 00507 * Convert the XML document tree into XML text data and place it into 00508 * the given filename. 00509 * 00510 * @param filename The name of the file to place the XML text data into. 00511 * @param compression_level 0 is no compression, 1-9 allowed, where 1 is for better speed, and 9 is for smaller size 00512 * @return True if the data was saved successfully. 00513 * @return False otherwise. 00514 * @author Peter Jones 00515 **/ 00516 //#################################################################### 00517 bool save_to_file (const char *filename, int compression_level=0) const; 00518 00519 //#################################################################### 00520 /** 00521 * Convert the XML document tree into XML text data and then insert it 00522 * into the given stream. 00523 * 00524 * @param stream The stream to insert the XML into. 00525 * @param doc The document to insert. 00526 * @return The stream from the first parameter. 00527 * @author Peter Jones 00528 **/ 00529 //#################################################################### 00530 friend std::ostream& operator<< (std::ostream &stream, const document &doc); 00531 00532 private: 00533 doc_impl *pimpl_; 00534 void set_doc_data (void *data); 00535 void set_doc_data_from_xslt (void *data, void *ss); 00536 void* get_doc_data (void); 00537 void* release_doc_data (void); 00538 00539 friend class tree_parser; 00540 friend class xslt::stylesheet; 00541 }; // end xml::document class 00542 00543 } // end xml namespace 00544 #endif