天天看點

tinyxml的使用方法(c++)

參見 TinyXml msdn. ·   TiXmlBase o      TiXmlAttribute o      TiXmlNode §         TiXmlComment §         TiXmlDeclaration §         TiXmlDocument §         TiXmlElement §         TiXmlText §         TiXmlUnknown

TiXmlHandle

1.加載檔案。

TiXmlDocument doc( "demo.xml" );

doc.LoadFile();

2.

void main(void)

{

 TiXmlDocument doc("example1.xml");

 bool loadOkay = doc.LoadFile();

 if (loadOkay)

 {

  printf("/n%s:/n", pFilename);

  dump_to_stdout( &doc ); // defined later in the tutorial

 }

 else

 {

  printf("Failed to load file /"%s/"/n", pFilename);

 }

 return;

}

example1.xml 的内容如果是:

<?xml version="1.0" ?>

<Hello>World</Hello>

輸出為:

DOCUMENT

+ DECLARATION

+ ELEMENT Hello

  + TEXT[World]

3.建立文檔的方法.

void build( )

{               TiXmlDocument doc;

 TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );

 TiXmlElement * element = new TiXmlElement( "Hello" );

 TiXmlText * text = new TiXmlText( "World" );

 element->LinkEndChild( text );

 doc.LinkEndChild( decl );

 doc.LinkEndChild( element );

 doc.SaveFile( "example1.xml" );

}

4.設定節點屬性。

TiXmlElement  window = new TiXmlElement( "Demo" );  

window->SetAttribute("name", "Circle");

window->SetAttribute("x", 5);

window->SetAttribute("y", 15);

window->SetDoubleAttribute("radius", 3.14159);

5.擷取元素的所有屬性,并列印出屬性名稱和值

int printElement(TiXmlElement* pElement, unsigned int indent)

{

 if ( !pElement ) return 0;

 TiXmlAttribute* pAttrib=pElement->FirstAttribute();

 int i=0;

 int ival;

 double dval;

 const char* pIndent=getIndent(indent);

 printf("/n");

 while (pAttrib)

 {

  printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());

  if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS)    printf( " int=%d", ival);

  if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);

  printf( "/n" );

  i++;

  pAttrib=pAttrib->Next();

 }

 return i;

}

6.寫入檔案,其實上面已經用到了。

doc.SaveFile( saveFilename );  

7.建立一個其内容如下的文檔:

<?xml version="1.0" ?>

<MyApp>

    <!-- Settings for MyApp -->

    <Messages>

        <Welcome>Welcome to MyApp</Welcome>

        <Farewell>Thank you for using MyApp</Farewell>

    </Messages>

    <Windows>

        <Window name="MainFrame" x="5" y="15" w="400" h="250" />

    </Windows>

    <Connection ip="192.168.0.1" timeout="123.456000" />

</MyApp>

void main( )  

{  

 TiXmlDocument doc;  

 TiXmlElement* msg;

  TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  //文檔聲明

 doc.LinkEndChild( decl );  

 TiXmlElement * root = new TiXmlElement( "MyApp" );  

 doc.LinkEndChild( root );  //根元素

 TiXmlComment * comment = new TiXmlComment();//xml注釋

 comment->SetValue(" Settings for MyApp " );  

 root->LinkEndChild( comment );  //插入根元素之間 

 TiXmlElement * msgs = new TiXmlElement( "Messages" );  

 root->LinkEndChild( msgs );  //定義元素Messages,插入到root

 msg = new TiXmlElement( "Welcome" );  //定義新元素,并插入到msgs 

 msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" ));  

 msgs->LinkEndChild( msg );  

 msg = new TiXmlElement( "Farewell" );  //定義新元素,并插入到msgs 

 msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" ));  

 msgs->LinkEndChild( msg );  

 TiXmlElement * windows = new TiXmlElement( "Windows" );  

 root->LinkEndChild( windows );  //root中插入新元素windows

 TiXmlElement * window;

 window = new TiXmlElement( "Window" );  

 windows->LinkEndChild( window );  //定義新元素,并設定其屬性。

 window->SetAttribute("name", "MainFrame");

 window->SetAttribute("x", 5);

 window->SetAttribute("y", 15);

 window->SetAttribute("w", 400);

 window->SetAttribute("h", 250);

 TiXmlElement * cxn = new TiXmlElement( "Connection" );  

 root->LinkEndChild( cxn );  

 cxn->SetAttribute("ip", "192.168.0.1");

 cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib

 dump_to_stdout( &doc );

 doc.SaveFile( "appsettings.xml" );  //儲存檔案

8.對象到XML的轉換。

///class

#include <string>

#include <map>

using namespace std;

typedef std::map<std::string,std::string> MessageMap;

// a basic window abstraction - demo purposes only

class WindowSettings

{

public:

 int x,y,w,h;

 string name;

 WindowSettings()

  : x(0), y(0), w(100), h(100), name("Untitled")

 {

 }

 WindowSettings(int x, int y, int w, int h, const string& name)

 {

  this->x=x;

  this->y=y;

  this->w=w;

  this->h=h;

  this->name=name;

 }

};

class ConnectionSettings

{

public:

 string ip;

 double timeout;

};

class AppSettings

{

public:

 string m_name;

 MessageMap m_messages;

 list<WindowSettings> m_windows;

 ConnectionSettings m_connection;

 AppSettings() {}

 void save(const char* pFilename);

 void load(const char* pFilename);

 // just to show how to do it

 void setDemoValues()

 {

  m_name="MyApp";

  m_messages.clear();

  m_messages["Welcome"]="Welcome to "+m_name;

  m_messages["Farewell"]="Thank you for using "+m_name;

  m_windows.clear();

  m_windows.push_back(WindowSettings(15,15,400,250,"Main"));

  m_connection.ip="Unknown";

  m_connection.timeout=123.456;

 }

};

///建立檔案,并加載

int main(void)

{

 AppSettings settings;

 settings.save("appsettings2.xml");

 settings.load("appsettings2.xml");

 return 0;

}

///建立,修改和儲存

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 & 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;

}

輸出:

HitchHikerApp: Don't Panic

HitchHikerApp: Show window 'BookFrame' at 15,25 (300 x 100)

HitchHikerApp: Thanks for all the fish

9.XML到對象的轉換。

void AppSettings::load(const char* pFilename)

{

 TiXmlDocument doc(pFilename);

 if (!doc.LoadFile()) return;

 TiXmlHandle hDoc(&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->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->NextSiblingElement())

  {

   const char *pKey=pElem->Value();

   const char *pText=pElem->GetText();

   if (pKey && 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->NextSiblingElement())

  {

   WindowSettings w;

   const char *pName=pWindowNode->Attribute("name");

   if (pName) w.name=pName;

   pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left 

as-is

   pWindowNode->QueryIntAttribute("y", &w.y);

   pWindowNode->QueryIntAttribute("w", &w.w);

   pWindowNode->QueryIntAttribute("hh", &w.h);

   m_windows.push_back(w);

  }

 }

 // block: connection

 {

  pElem=hRoot.FirstChild("Connection").Element();

  if (pElem)

  {

   m_connection.ip=pElem->Attribute("ip");

   pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);

  }

 }

}

10.一個比較完整的例子,加載任意的XML文檔,并在控制台上輸出。

//

#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 > LENGTH ) n = LENGTH;

 return &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 > LENGTH ) n = LENGTH;

 return &pINDENT[ LENGTH-n ];

}

int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent)

{

 if ( !pElement ) return 0;

 TiXmlAttribute* pAttrib=pElement->FirstAttribute();

 int i=0;

 int ival;

 double dval;

 const char* pIndent=getIndent(indent);

 printf("/n");

 while (pAttrib)

 {

  printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());

  if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS)    printf( " int=%d", ival);

  if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);

  printf( "/n" );

  i++;

  pAttrib=pAttrib->Next();

 }

 return i; 

}

void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 )

{

 if ( !pParent ) return;

 TiXmlNode* pChild;

 TiXmlText* pText;

 int t = pParent->Type();

 printf( "%s", getIndent(indent));

 int num;

 switch ( t )

 {

 case TiXmlNode::DOCUMENT:

  printf( "Document" );

  break;

 case TiXmlNode::ELEMENT:

  printf( "Element [%s]", pParent->Value() );

  num=dump_attribs_to_stdout(pParent->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->Value());

  break;

 case TiXmlNode::UNKNOWN:

  printf( "Unknown" );

  break;

 case TiXmlNode::TEXT:

  pText = pParent->ToText();

  printf( "Text: [%s]", pText->Value() );

  break;

 case TiXmlNode::DECLARATION:

  printf( "Declaration" );

  break;

 default:

  break;

 }

 printf( "/n" );

 for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->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( &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<argc; i++)

 {

  dump_to_stdout(argv[i]);

 }

 return 0;

}