📄 txml.hpp
字号:
*/
bool load_file( FILE*, encoding encoding_ = TIXML_DEFAULT_ENCODING );
/// Save a file_ using the given FILE*. Returns true if successful.
bool save_file( FILE* ) const;
#ifdef TIXML_USE_STL
bool load_file( const std::string& filename, encoding encoding_ = TIXML_DEFAULT_ENCODING ) ///< STL std::string version_.
{
// StringToBuffer f( filename );
// return ( f.buffer && load_file( f.buffer, encoding_ ));
return load_file( filename.c_str(), encoding_ );
}
bool load_file( const std::wstring& filename, encoding encoding_ = TIXML_DEFAULT_ENCODING ) ///< STL std::string version_.
{
// StringToBuffer f( filename );
// return ( f.buffer && load_file( f.buffer, encoding_ ));
return load_file( filename.c_str(), encoding_ );
}
bool save_file( const std::string& filename ) const ///< STL std::string version_.
{
// StringToBuffer f( filename );
// return ( f.buffer && save_file( f.buffer ));
return save_file( filename.c_str() );
}
bool save_file( const std::wstring& filename ) const ///< STL std::string version_.
{
// StringToBuffer f( filename );
// return ( f.buffer && save_file( f.buffer ));
return save_file( filename.c_str() );
}
#endif
/** parse the given null terminated block of xml data. Passing in an encoding_ to this
method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
to use that encoding_, regardless of what TinyXml might otherwise try to detect.
*/
virtual const char* parse( const char* p, parsing_data* data = 0, encoding encoding_ = TIXML_DEFAULT_ENCODING );
/** Get the root_ element_ -- the only top_ level element_ -- of the document_.
In well formed XML, there should only be one. TinyXml is tolerant of
multiple elements at the document_ level.
*/
const element* root_element() const { return first_child_element(); }
element* root_element() { return first_child_element(); }
/** If an error_ occurs, error will be set to true. Also,
- The error_id() will contain the integer identifier of the error_ (not generally useful)
- The error_desc() method will return the name_ of the error_. (very useful)
- The error_row() and error_col() will return the location_ of the error_ (if known)
*/
bool error() const { return error_; }
/// Contains a textual (english) description of the error_ if one occurs.
const char * error_desc() const { return errorDesc.c_str (); }
/** Generally, you probably want the error_ string ( error_desc() ). But if you
prefer the error_id, this function will fetch it_.
*/
int error_id() const { return errorId; }
/** Returns the location_ (if known) of the error_. The first_ column_ is column_ 1,
and the first_ row_ is row_ 1. A value_ of 0 means the row_ and column_ wasn't applicable
(memory_ errors, for example, have no_ row_/column_) or the parser lost the error_. (An
error_ in the error_ reporting, in that case.)
@sa set_tab_size, row, column
*/
int error_row() const { return errorLocation.row_+1; }
int error_col() const { return errorLocation.col+1; } ///< The column_ where the error_ occured. See error_row()
/** set_tab_size() allows the error_ reporting functions (error_row() and error_col())
to report the correct_ values for row_ and column_. it does not change the output_
or input in any way.
By calling this method, with a tab_ size
greater than 0, the row_ and column_ of each node_ and attribute_ is stored
when the file_ is loaded. Very useful for tracking the DOM back in to
the source file_.
The tab_ size is required for calculating the location_ of nodes. If not
set, the default of 4 is used. The tabsize is set per document_. Setting
the tabsize to 0 disables row_/column_ tracking.
Note that row_ and column_ tracking is not supported when using operator>>.
The tab_ size needs to be enabled before the parse_ or load. correct usage:
@verbatim
document doc;
doc.set_tab_size( 8 );
doc.Load( "myfile.xml" );
@endverbatim
@sa row, column
*/
void set_tab_size( int _tabsize ) { tabsize = _tabsize; }
int tab_size() const { return tabsize; }
/** If you have handled the error_, it_ can be reset with this call. The error_
state is automatically cleared if you parse a new XML block.
*/
void clear_error() { error_ = false;
errorId = 0;
errorDesc = "";
errorLocation.row_ = errorLocation.col = 0;
//errorLocation.last_ = 0;
}
/** Write the document_ to standard out using formatted printing_ ("pretty print"). */
void print() const { print( stdout, 0 ); }
/* Write the document_ to a string using formatted printing_ ("pretty print"). this
will allocate a character array (new char[]) and return it_ as a pointer. The
calling code pust call delete[] on the return char* to avoid a memory_ leak.
*/
//char* PrintToMemory() const;
/// print this document to a FILE stream_.
virtual void print( FILE* cfile, int depth = 0 ) const;
// [internal use]
void set_error( int err, const char* errorLocation, parsing_data* prevData, encoding encoding_ );
virtual const document* to_document() const { return this; } ///< Cast to a more defined type_. Will return null not of the requested type_.
virtual document* to_document() { return this; } ///< Cast to a more defined type_. Will return null not of the requested type_.
/** Walk the XML tree visiting this node_ and all of its children_.
*/
virtual bool accept( visitor* content ) const;
protected :
// [internal use]
virtual node* clone() const;
#ifdef TIXML_USE_STL
virtual void stream_in( std::istream * in, TIXML_STRING * tag );
#endif
private:
void copy_to( document* target ) const;
bool error_;
int errorId;
TIXML_STRING errorDesc;
int tabsize;
cursor errorLocation;
bool useMicrosoftBOM; // the UTF-8 BOM were found when read_. Note this, and try to write.
};
/**
A handle is a class that wraps a node_ pointer with null checks; this is
an incredibly useful thing. Note that handle is not part of the TinyXml
DOM structure. it is a separate utility class.
Take an example:
@verbatim
<document>
<element attributeA = "valueA">
<child attributeB = "value1" />
<child attributeB = "value2" />
</element>
<document>
@endverbatim
Assuming you want the value_ of "attributeB" in the 2nd "Child" element_, it_'s very
easy to write a *lot* of code that looks like:
@verbatim
element* root_ = document_.first_child_element( "Document" );
if ( root_ )
{
element* element_ = root_->first_child_element( "Element" );
if ( element_ )
{
element* child_ = element_->first_child_element( "Child" );
if ( child_ )
{
element* child2 = child_->next_sibling_element( "Child" );
if ( child2 )
{
// Finally do_ something useful.
@endverbatim
And that doesn't even cover "else" cases. handle addresses the verbosity
of such code. A handle checks for null pointers so it_ is perfectly safe
and correct_ to use:
@verbatim
handle docHandle( &document_ );
element* child2 = docHandle.first_child( "Document" ).first_child( "Element" ).child( "Child", 1 ).to_element();
if ( child2 )
{
// do_ something useful
@endverbatim
Which is MUCH more concise and useful.
it is also safe to copy_ handles - internally they are_ nothing more than node_ pointers.
@verbatim
handle handleCopy = handle_;
@endverbatim
What they should not be used for is iteration:
@verbatim
int i=0;
while ( true )
{
element* child_ = docHandle.first_child( "Document" ).first_child( "Element" ).child( "Child", i ).to_element();
if ( !child_ )
break;
// do_ something
++i;
}
@endverbatim
it seems reasonable, but it_ is in fact two embedded_ while loops. The child method is
a linear walk to find the element_, so this code would iterate much more than it_ needs
to. Instead, prefer:
@verbatim
element* child_ = docHandle.first_child( "Document" ).first_child( "Element" ).first_child( "Child" ).to_element();
for( child_; child_; child_=child_->next_sibling_element() )
{
// do_ something
}
@endverbatim
*/
class handle
{
public:
/// Create a handle_ from any node_ (at any depth of the tree.) this can be a null pointer.
handle( node* _node ) { this->node_ = _node; }
/// copy constructor
handle( const handle& ref ) { this->node_ = ref.node_; }
handle operator=( const handle& ref ) { this->node_ = ref.node_; return *this; }
/// Return a handle_ to the first_ child_ node_.
handle first_child() const;
/// Return a handle_ to the first_ child_ node_ with the given name_.
handle first_child( const char * value_ ) const;
/// Return a handle_ to the first_ child_ element_.
handle first_child_element() const;
/// Return a handle_ to the first_ child_ element_ with the given name_.
handle first_child_element( const char * value_ ) const;
/** Return a handle_ to the "index" child_ with the given name_.
The first_ child_ is 0, the second 1, etc.
*/
handle child( const char* value_, int index ) const;
/** Return a handle_ to the "index" child_.
The first_ child_ is 0, the second 1, etc.
*/
handle child( int index ) const;
/** Return a handle_ to the "index" child_ element_ with the given name_.
The first_ child_ element_ is 0, the second 1, etc. Note that only TiXmlElements
are_ indexed: other types are_ not counted.
*/
handle child_element( const char* value_, int index ) const;
/** Return a handle_ to the "index" child_ element_.
The first_ child_ element_ is 0, the second 1, etc. Note that only TiXmlElements
are_ indexed: other types are_ not counted.
*/
handle child_element( int index ) const;
#ifdef TIXML_USE_STL
handle first_child( const std::string& _value ) const { return first_child( _value.c_str() ); }
handle first_child_element( const std::string& _value ) const { return first_child_element( _value.c_str() ); }
handle child( const std::string& _value, int index ) const { return child( _value.c_str(), index ); }
handle child_element( const std::string& _value, int index ) const { return child_element( _value.c_str(), index ); }
#endif
/** Return the handle_ as a node. this may return null.
*/
node* to_node() const { return node_; }
/** Return the handle_ as a element. this may return null.
*/
element* to_element() const { return ( ( node_ && node_->to_element() ) ? node_->to_element() : 0 ); }
/** Return the handle_ as a text. this may return null.
*/
text* to_text() const { return ( ( node_ && node_->to_text() ) ? node_->to_text() : 0 ); }
/** Return the handle_ as a unknown. this may return null.
*/
unknown* to_unknown() const { return ( ( node_ && node_->to_unknown() ) ? node_->to_unknown() : 0 ); }
private:
node* node_;
};
/** print to memory_ functionality. The printer is useful when you need to:
-# print to memory_ (especially in non-STL mode)
-# Control formatting (line_ endings, etc.)
When constructed, the printer is in its default "pretty printing" mode.
Before calling accept() you can call methods to control the printing_
of the XML document_. After node::accept() is called, the printed document_ can
be accessed via the CStr(), str(), and size() methods.
printer uses the Visitor API.
@verbatim
printer printer_;
printer_.set_indent( "\t" );
doc.accept( &printer_ );
fprintf( stdout, "%s", printer_.CStr() );
@endverbatim
*/
class printer : public visitor
{
public:
printer() : depth( 0 ), simpleTextPrint( false ),
buffer(), indent_( " " ), lineBreak( "\n" ) {}
virtual bool visit_enter( const document& doc );
virtual bool visit_exit( const document& doc );
virtual bool visit_enter( const element& element_, const attribute* firstAttribute );
virtual bool visit_exit( const element& element_ );
virtual bool visit( const declaration& declaration_ );
virtual bool visit( const text& text_ );
virtual bool visit( const comment& comment_ );
virtual bool visit( const unknown& unknown_ );
/** Set the indent_ characters for printing_. By default 4 spaces
but tab_ (\t) is also useful, or null/empty string for no_ indentation.
*/
void set_indent( const char* _indent ) { indent_ = _indent ? _indent : "" ; }
/// query the indention string.
const char* indent() { return indent_.c_str(); }
/** Set the line_ breaking string. By default set to newline (\n).
Some operating systems prefer other characters, or can be
set to the null/empty string for no_ indenation.
*/
void set_line_break( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
/// query the current line_ breaking string.
const char* line_break() { return lineBreak.c_str(); }
/** Switch over to "stream printing" which is the most dense formatting without
linebreaks. Common when the XML is needed for network transmission.
*/
void set_stream_printing() { indent_ = "";
lineBreak = "";
}
/// Return the result.
const char* CStr() { return buffer.c_str(); }
/// Return the length of the result string.
size_t size() { return buffer.size(); }
#ifdef TIXML_USE_STL
/// Return the result.
const std:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -