⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tutorial0.html

📁 xml 简单解析器
💻 HTML
📖 第 1 页 / 共 2 页
字号:
	AppSettings settings;
	
	settings.save("appsettings2.xml");
	settings.load("appsettings2.xml");
	return 0;
}
</pre></div><p>
The following main() shows creation, modification, saving and then loading of a settings structure:<p>
<div class="fragment"><pre class="fragment">int main(void)
{
	// block: customise and save settings
	{
		AppSettings settings;
		settings.m_name="HitchHikerApp";
		settings.m_messages["Welcome"]="Don't Panic";
		settings.m_messages["Farewell"]="Thanks for all the fish";
		settings.m_windows.push_back(WindowSettings(15,25,300,250,"BookFrame"));
		settings.m_connection.ip="192.168.0.77";
		settings.m_connection.timeout=42.0;

		settings.save("appsettings2.xml");
	}
	
	// block: load settings
	{
		AppSettings settings;
		settings.load("appsettings2.xml");
		printf("%s: %s\n", settings.m_name.c_str(), 
			settings.m_messages["Welcome"].c_str());
		WindowSettings &amp; w=settings.m_windows.front();
		printf("%s: Show window '%s' at %d,%d (%d x %d)\n", 
			settings.m_name.c_str(), w.name.c_str(), w.x, w.y, w.w, w.h);
		printf("%s: %s\n", settings.m_name.c_str(), settings.m_messages["Farewell"].c_str());
	}
	return 0;
}
</pre></div><p>
When the save() and load() are completed (see below), running this main() displays on the console:<p>
<div class="fragment"><pre class="fragment">HitchHikerApp: Don't Panic
HitchHikerApp: Show window 'BookFrame' at 15,25 (300 x 100)
HitchHikerApp: Thanks for all the fish
</pre></div><p>
<h2>Encode C++ state as XML </h2>
<p>
There are lots of different ways to approach saving this to a file. Here's one:<p>
<div class="fragment"><pre class="fragment">void AppSettings::save(const char* pFilename)
{
	TiXmlDocument doc;  
	TiXmlElement* msg;
	TiXmlComment * comment;
	string s;
 	TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  
	doc.LinkEndChild( decl ); 
 
	TiXmlElement * root = new TiXmlElement(m_name.c_str());  
	doc.LinkEndChild( root );  

	comment = new TiXmlComment();
	s=" Settings for "+m_name+" ";
	comment-&gt;SetValue(s.c_str());  
	root-&gt;LinkEndChild( comment );  

	// block: messages
	{
		MessageMap::iterator iter;

		TiXmlElement * msgs = new TiXmlElement( "Messages" );  
		root-&gt;LinkEndChild( msgs );  
 
		for (iter=m_messages.begin(); iter != m_messages.end(); iter++)
		{
			const string &amp; key=(*iter).first;
			const string &amp; value=(*iter).second;
			msg = new TiXmlElement(key.c_str());  
			msg-&gt;LinkEndChild( new TiXmlText(value.c_str()));  
			msgs-&gt;LinkEndChild( msg );  
		}
	}

	// block: windows
	{
		TiXmlElement * windowsNode = new TiXmlElement( "Windows" );  
		root-&gt;LinkEndChild( windowsNode );  

		list&lt;WindowSettings&gt;::iterator iter;

		for (iter=m_windows.begin(); iter != m_windows.end(); iter++)
		{
			const WindowSettings&amp; w=*iter;

			TiXmlElement * window;
			window = new TiXmlElement( "Window" );  
			windowsNode-&gt;LinkEndChild( window );  
			window-&gt;SetAttribute("name", w.name.c_str());
			window-&gt;SetAttribute("x", w.x);
			window-&gt;SetAttribute("y", w.y);
			window-&gt;SetAttribute("w", w.w);
			window-&gt;SetAttribute("h", w.h);
		}
	}

	// block: connection
	{
		TiXmlElement * cxn = new TiXmlElement( "Connection" );  
		root-&gt;LinkEndChild( cxn );  
		cxn-&gt;SetAttribute("ip", m_connection.ip.c_str());
		cxn-&gt;SetDoubleAttribute("timeout", m_connection.timeout); 
	}

	doc.SaveFile(pFilename);  
}
</pre></div><p>
Running this with the modified main produces this file:<p>
<div class="fragment"><pre class="fragment">&lt;?xml version="1.0" ?&gt;
&lt;HitchHikerApp&gt;
    &lt;!-- Settings for HitchHikerApp --&gt;
    &lt;Messages&gt;
        &lt;Farewell&gt;Thanks for all the fish&lt;/Farewell&gt;
        &lt;Welcome&gt;Don&amp;apos;t Panic&lt;/Welcome&gt;
    &lt;/Messages&gt;
    &lt;Windows&gt;
        &lt;Window name="BookFrame" x="15" y="25" w="300" h="250" /&gt;
    &lt;/Windows&gt;
    &lt;Connection ip="192.168.0.77" timeout="42.000000" /&gt;
&lt;/HitchHikerApp&gt;
</pre></div><p>
<h2>Decoding state from XML </h2>
<p>
As with encoding objects, there are a number of approaches to decoding XML into your own C++ object structure. The following approach uses TiXmlHandles.<p>
<div class="fragment"><pre class="fragment">void AppSettings::load(const char* pFilename)
{
	TiXmlDocument doc(pFilename);
	if (!doc.LoadFile()) return;

	TiXmlHandle hDoc(&amp;doc);
	TiXmlElement* pElem;
	TiXmlHandle hRoot(0);

	// block: name
	{
		pElem=hDoc.FirstChildElement().Element();
		// should always have a valid root but handle gracefully if it does
		if (!pElem) return;
		m_name=pElem-&gt;Value();

		// save this for later
		hRoot=TiXmlHandle(pElem);
	}

	// block: string table
	{
		m_messages.clear(); // trash existing table

		pElem=hRoot.FirstChild( "Messages" ).FirstChild().Element();
		for( pElem; pElem; pElem=pElem-&gt;NextSiblingElement())
		{
			const char *pKey=pElem-&gt;Value();
			const char *pText=pElem-&gt;GetText();
			if (pKey &amp;&amp; pText) 
			{
				m_messages[pKey]=pText;
			}
		}
	}

	// block: windows
	{
		m_windows.clear(); // trash existing list

		TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();
		for( pWindowNode; pWindowNode; pWindowNode=pWindowNode-&gt;NextSiblingElement())
		{
			WindowSettings w;
			const char *pName=pWindowNode-&gt;Attribute("name");
			if (pName) w.name=pName;
			
			pWindowNode-&gt;QueryIntAttribute("x", &amp;w.x); // If this fails, original value is left as-is
			pWindowNode-&gt;QueryIntAttribute("y", &amp;w.y);
			pWindowNode-&gt;QueryIntAttribute("w", &amp;w.w);
			pWindowNode-&gt;QueryIntAttribute("hh", &amp;w.h);

			m_windows.push_back(w);
		}
	}

	// block: connection
	{
		pElem=hRoot.FirstChild("Connection").Element();
		if (pElem)
		{
			m_connection.ip=pElem-&gt;Attribute("ip");
			pElem-&gt;QueryDoubleAttribute("timeout",&amp;m_connection.timeout);
		}
	}
}
</pre></div><p>
<h1>Full listing for dump_to_stdout </h1>
<p>
Below is a copy-and-paste demo program for loading arbitrary XML files and dumping the structure to STDOUT using the recursive traversal listed above.<p>
<div class="fragment"><pre class="fragment">// tutorial demo program
#include "stdafx.h"
#include "tinyxml.h"

// ----------------------------------------------------------------------
// STDOUT dump and indenting utility functions
// ----------------------------------------------------------------------
const unsigned int NUM_INDENTS_PER_SPACE=2;

const char * getIndent( unsigned int numIndents )
{
	static const char * pINDENT="                                      + ";
	static const unsigned int LENGTH=strlen( pINDENT );
	unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
	if ( n &gt; LENGTH ) n = LENGTH;

	return &amp;pINDENT[ LENGTH-n ];
}

// same as getIndent but no "+" at the end
const char * getIndentAlt( unsigned int numIndents )
{
	static const char * pINDENT="                                        ";
	static const unsigned int LENGTH=strlen( pINDENT );
	unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
	if ( n &gt; LENGTH ) n = LENGTH;

	return &amp;pINDENT[ LENGTH-n ];
}

int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent)
{
	if ( !pElement ) return 0;

	TiXmlAttribute* pAttrib=pElement-&gt;FirstAttribute();
	int i=0;
	int ival;
	double dval;
	const char* pIndent=getIndent(indent);
	printf("\n");
	while (pAttrib)
	{
		printf( "%s%s: value=[%s]", pIndent, pAttrib-&gt;Name(), pAttrib-&gt;Value());

		if (pAttrib-&gt;QueryIntValue(&amp;ival)==TIXML_SUCCESS)    printf( " int=%d", ival);
		if (pAttrib-&gt;QueryDoubleValue(&amp;dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
		printf( "\n" );
		i++;
		pAttrib=pAttrib-&gt;Next();
	}
	return i;	
}

void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 )
{
	if ( !pParent ) return;

	TiXmlNode* pChild;
	TiXmlText* pText;
	int t = pParent-&gt;Type();
	printf( "%s", getIndent(indent));
	int num;

	switch ( t )
	{
	case TiXmlNode::DOCUMENT:
		printf( "Document" );
		break;

	case TiXmlNode::ELEMENT:
		printf( "Element [%s]", pParent-&gt;Value() );
		num=dump_attribs_to_stdout(pParent-&gt;ToElement(), indent+1);
		switch(num)
		{
			case 0:  printf( " (No attributes)"); break;
			case 1:  printf( "%s1 attribute", getIndentAlt(indent)); break;
			default: printf( "%s%d attributes", getIndentAlt(indent), num); break;
		}
		break;

	case TiXmlNode::COMMENT:
		printf( "Comment: [%s]", pParent-&gt;Value());
		break;

	case TiXmlNode::UNKNOWN:
		printf( "Unknown" );
		break;

	case TiXmlNode::TEXT:
		pText = pParent-&gt;ToText();
		printf( "Text: [%s]", pText-&gt;Value() );
		break;

	case TiXmlNode::DECLARATION:
		printf( "Declaration" );
		break;
	default:
		break;
	}
	printf( "\n" );
	for ( pChild = pParent-&gt;FirstChild(); pChild != 0; pChild = pChild-&gt;NextSibling()) 
	{
		dump_to_stdout( pChild, indent+1 );
	}
}

// load the named file and dump its structure to STDOUT
void dump_to_stdout(const char* pFilename)
{
	TiXmlDocument doc(pFilename);
	bool loadOkay = doc.LoadFile();
	if (loadOkay)
	{
		printf("\n%s:\n", pFilename);
		dump_to_stdout( &amp;doc ); // defined later in the tutorial
	}
	else
	{
		printf("Failed to load file \"%s\"\n", pFilename);
	}
}

// ----------------------------------------------------------------------
// main() for printing files named on the command line
// ----------------------------------------------------------------------
int main(int argc, char* argv[])
{
	for (int i=1; i&lt;argc; i++)
	{
		dump_to_stdout(argv[i]);
	}
	return 0;
}
</pre></div><p>
Run this from the command line or a DOS window, e.g.:<p>
<div class="fragment"><pre class="fragment">C:\dev\tinyxml&gt; Debug\tinyxml_1.exe example1.xml

example1.xml:
Document
+ Declaration
+ Element [Hello]
 (No attributes)
  + Text: [World]
</pre></div><p>
<em> Authors and Changes <ul>
<li>
Written by Ellers, April, May, June 2005  </li>
<li>
Minor edits and integration into doc system, Lee Thomason September 2005  </li>
<li>
Updated by Ellers, October 2005  </li>
</ul>
</em> <hr size="1"><address style="align: right;"><small>Generated on Sun Jan 15 23:12:05 2006 for TinyXml by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.4 </small></address>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -