小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

TinyXML應(yīng)用例子

 Delores 2008-02-18
完整顯示   1 2

開發(fā)軟件時(shí)經(jīng)常需要把一些東西做成可配置的,于是就需要用到配置文件,以前多是用ini文件,然后自己寫個(gè)類來解析?,F(xiàn)在有了XML,許多應(yīng)用軟件就喜歡把配置文件做成XML格式。但是如果我們的程序本身很小,為了讀取個(gè)配置文件卻去用Xerces XML之類的庫,恐怕會得不償失。那么用TinyXML吧,它很小,只有六個(gè)文件,加到項(xiàng)目中就可以開始我們的配置文件之旅了。

前些時(shí)候我恰好就用TinyXML寫了一個(gè)比較通用的配置文件類,基本可以適應(yīng)大部分的場合,不過配置文件只支持兩層結(jié)構(gòu),如果需要支持多層嵌套結(jié)構(gòu),那還需要稍加擴(kuò)展一下。

從下面的源代碼中,你也可以看到怎么去使用TinyXML,也算是它的一個(gè)應(yīng)用例子了。

 

/*
** FileName:    config.h
** Author:        hansen
** Date:        May 11, 2007
** Comment:        配置文件類,主要用來讀取xml配置文件中的一些配置信息
*/

 
#ifndef _CONFIG
#define _CONFIG
 
#include <string>
#include "tinyxml.h"
 
using namespace std;
 
class CConfig
{
public:
    explicit CConfig(const char* xmlFileName)
        :mXmlConfigFile(xmlFileName),mRootElem(0)
    {
        //加載配置文件
        mXmlConfigFile.LoadFile();    
        
        //得到配置文件的根結(jié)點(diǎn)
        mRootElem=mXmlConfigFile.RootElement();
    }
 
public:
    //得到nodeName結(jié)點(diǎn)的值
    string GetValue(const string& nodeName);
 
private:
    //禁止默認(rèn)構(gòu)造函數(shù)被調(diào)用
    CMmsConfig();
 
private:
    TiXmlDocument    mXmlConfigFile;
    TiXmlElement*    mRootElem;
 
};
 
#endif

 

 

/*
** FileName:    config.cpp
** Author:        hansen
** Date:        May 11, 2007
** Comment:        
*/

 
#include "config.h"
#include <iostream>
 
string CConfig::GetValue(const string& nodeName)
{
    if(!mRootElem)
    {
        cout<<"讀取根結(jié)點(diǎn)出錯(cuò)"<<endl;
        return "";
    }
 
    TiXmlElement* pElem=mRootElem->FirstChildElement(nodeName.c_str());
    if(!pElem)
    {
        cout<<"讀取"<<nodeName<<"結(jié)點(diǎn)出錯(cuò)"<<endl;
        return "";
    }
 
    return pElem->GetText();
 
}
 
 
int main()
{
    CConfig xmlConfig("XmlConfig.xml");
 
    //獲取Author的值
    string author = xmlConfig.GetValue("Author");
    cout<<"Author:"<<author<<endl;
 
    //獲取Site的值
    string site = xmlConfig.GetValue("Site");
    cout<<"Site:"<<site<<endl;
 
    //獲取Desc的值
    string desc = xmlConfig.GetValue("Desc");
    cout<<"Desc:"<<desc<<endl;
    
    return 0;
}

 

假設(shè)配置文件是這樣的:

<!– XmlConfig.xml –> 
<?xml version="1.0" encoding="GB2312" ?>
<Config>
    <Author>hansen</Author>
    <Site>www.</Site>
    <Desc>這是個(gè)測試程序</Desc>
</Config>

 

怎么使用上面的配置類來讀取XmlConfig.xml文件中的配置呢?很簡單:

int main()
{
    CConfig xmlConfig("XmlConfig.xml");
 
    //獲取Author的值
    string author = xmlConfig.GetValue("Author");
    cout<<"Author:"<<author<<endl;
 
    //獲取Site的值
    string site = xmlConfig.GetValue("Site");
    cout<<"Site:"<<site<<endl;
 
    //獲取Desc的值
    string desc = xmlConfig.GetValue("Desc");
    cout<<"Desc:"<<desc<<endl;
    
    return 0;
}

 

運(yùn)行結(jié)果如下:

D:\config\Debug>config.exe
Author:hansen
Site:www.
Desc:這是個(gè)測試程序

 

完整顯示   1 2
六月 09
完整顯示   1 2 3 4

 

譯注:本文是TinyXML 2.5.2版本Tutorial的中文譯文,經(jīng)原作者Lee Thomason同意由hansen翻譯,如有誤譯或者錯(cuò)漏,歡迎指正。
版權(quán):版權(quán)歸原作者所有,翻譯文檔版權(quán)歸本人hansen所有,轉(zhuǎn)載請注明出處。
原文:http://www./tinyxmldocs/tutorial0.html


 

TinyXML 指南

 

這是什么?

這份指南有一些關(guān)于如何有效地使用TinyXML的技巧和建議。

我也會嘗試講一些諸如怎樣使字符串與整型數(shù)相互轉(zhuǎn)化的C++技巧。這與TinyXML本身沒什么關(guān)系,但它也許會對你的項(xiàng)目有所幫助,所以我還是把它加進(jìn)來了。

如果你不知道基本的C++概念,那么這份指南就沒什么用了。同樣的,如果你不知道什么是DOM,那先從其它地方找來看看吧。

在我們開始之前

一些將會被用到的XML數(shù)據(jù)集/文件。

example1.xml:

 

<?xml version="1.0" ?>
<Hello>World</Hello>

example2.xml:

 

<?xml version="1.0" ?>
<poetry>
   <verse>
      Alas
         Great World
            Alas (again)
   </verse>
</poetry>

example3.xml:

 

<?xml version="1.0" ?>
<shapes>
   <circle name="int-based" x="20" y="30" r="50" />
   <point name="float-based" x="3.5" y="52.1" />
</shapes>

example4.xml:

 

<?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>

開始

把文件加載成XML

把一個(gè)文件加載成TinyXML DOM的最簡單方法是:

 

TiXmlDocument doc( "demo.xml" );
doc.LoadFile();

一個(gè)更接近于現(xiàn)實(shí)應(yīng)用的例子如下。它加載文件并把內(nèi)容顯示到標(biāo)準(zhǔn)輸出STDOUT上:

 

// 加載指定的文件并把它的結(jié)構(gòu)輸出到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 ); // 稍后在指南中定義
    }
    else
    {
        printf("Failed to load file \"%s\”\n", pFilename);
    }
}

在main中使用此函數(shù)的一個(gè)簡單應(yīng)用示范如下:

 

int main(void)
{
    dump_to_stdout("example1.xml");
    return 0;
}

回想example1的XML:

 

<?xml version="1.0" ?>
<Hello>World</Hello>

用這個(gè)XML運(yùn)行程序就會在控制臺/DOS窗口中顯示:

 

DOCUMENT
+ DECLARATION
+ ELEMENT Hello
  + TEXT[World]

”dump_to_stdout“函數(shù)稍后會在這份指南中定義,如果你想要理解怎樣遞歸遍歷一個(gè)DOM它會很有用。

用程序建立文檔對象

這是用程序建立example1的方法:

 

void build_simple_doc( )
{
    // 生成xml: <?xml ..><Hello>World</Hello>
    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( "madeByHand.xml" );
}

然后可以用以下方法加載并顯示在控制臺上:

 

dump_to_stdout("madeByHand.xml"); // 此函數(shù)稍后會中指南中定義

你會看到跟example1一模一樣:

 

madeByHand.xml:
Document
+ Declaration
+ Element [Hello]
  + Text: [World]

這段代碼會產(chǎn)生相同的XML DOM,但它以不同的順序來創(chuàng)建和鏈接結(jié)點(diǎn):

 

void write_simple_doc2( )
{
    // 實(shí)現(xiàn)與 write_simple_doc1一樣的功能,(譯注:我想它指是build_simple_doc)
    // 但盡可能早地把結(jié)點(diǎn)添加到樹中。
    TiXmlDocument doc;
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0""""" );
    doc.LinkEndChild( decl );
    
    TiXmlElement * element = new TiXmlElement( "Hello" );
    doc.LinkEndChild( element );
    
    TiXmlText * text = new TiXmlText( "World" );
    element->LinkEndChild( text );
    
    doc.SaveFile( "madeByHand2.xml" );
}

兩個(gè)都產(chǎn)生同樣的XML,即:

 

<?xml version="1.0" ?>
<Hello>World</Hello>

結(jié)構(gòu)構(gòu)成都是:

 

DOCUMENT
+ DECLARATION
+ ELEMENT Hello
  + TEXT[World]

屬性

給定一個(gè)存在的結(jié)點(diǎn),設(shè)置它的屬性是很容易的:

 

window = new TiXmlElement( "Demo" ); 
window->SetAttribute("name""Circle");
window->SetAttribute("x", 5);
window->SetAttribute("y", 15);
window->SetDoubleAttribute("radius", 3.14159);

你也可以用TiXmlAttribute對象達(dá)到同樣的目的。

下面的代碼向我們展示了一種(并不只有一種)獲取某一元素屬性并打印出它們的名字和字符串值的方法,如果值能夠被轉(zhuǎn)化為整型數(shù)或者浮點(diǎn)數(shù),也把值打印出來:

 

// 打印pElement的所有屬性。
// 返回已打印的屬性數(shù)量。
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;
}

把文檔對象寫到文件中

把一個(gè)已經(jīng)建立好的DOM寫到文件中是非常簡單的:

 

doc.SaveFile( saveFilename );

回想一下,比如example4:

 

<?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>

以下函數(shù)建立這個(gè)DOM并把它寫到“appsettings.xml”文件中:

 

void write_app_settings_doc( ) 

    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();
    comment->SetValue(" Settings for MyApp " ); 
    root->LinkEndChild( comment ); 
    
    TiXmlElement * msgs = new TiXmlElement( "Messages" ); 
    root->LinkEndChild( msgs ); 
    
    msg = new TiXmlElement( "Welcome" ); 
    msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" )); 
    msgs->LinkEndChild( msg ); 
    
    msg = new TiXmlElement( "Farewell" ); 
    msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" )); 
    msgs->LinkEndChild( msg ); 
    
    TiXmlElement * windows = new TiXmlElement( "Windows" ); 
    root->LinkEndChild( 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); // 浮點(diǎn)數(shù)屬性
    
    dump_to_stdout( &doc );
    doc.SaveFile( "appsettings.xml" ); 
}

dump_to_stdout函數(shù)將顯示如下結(jié)構(gòu):

 

Document
+ Declaration
+ Element [MyApp]
  (No attributes)
  + Comment: [ Settings for MyApp ]
  + Element [Messages]
  (No attributes)
    + Element [Welcome]
  (No attributes)
      + Text: [Welcome to MyApp]
    + Element [Farewell]
  (No attributes)
      + Text: [Thank you for using MyApp]
  + Element [Windows]
  (No attributes)
    + Element [Window]
      + name: value=[MainFrame]
      + x: value=[5] int=5 d=5.0
      + y: value=[15] int=15 d=15.0
      + w: value=[400] int=400 d=400.0
      + h: value=[250] int=250 d=250.0
      5 attributes
  + Element [Connection]
    + ip: value=[192.168.0.1] int=192 d=192.2
    + timeout: value=[123.456000] int=123 d=123.5
    2 attributes

TinyXML默認(rèn)以其它APIs稱作“pretty”格式的方式來輸出XML,對此我感到驚訝。這種格式修改了元素的文本結(jié)點(diǎn)中的空格,以使輸出來的結(jié)點(diǎn)樹包含一個(gè)嵌套層標(biāo)記。

我還沒有仔細(xì)看當(dāng)寫到一個(gè)文件中時(shí)是否有辦法關(guān)閉這種縮進(jìn)——這肯定很容易做到。(譯注:這兩句話大概是Ellers說的

[Lee:在STL模式下這很容易做到,只需要cout << myDoc就行了。在非STL模式下就總是用“pretty”格式了,加多一個(gè)開關(guān)是一個(gè)很好的特性,這已經(jīng)被要求過了。]

XML與C++對象的相互轉(zhuǎn)化

介紹

這個(gè)例子假設(shè)你在用一個(gè)XML文件來加載和保存你的應(yīng)用程序配置,舉例來說,有點(diǎn)像example4.xml。

有許多方法可以做到這點(diǎn)。例如,看看TinyBind項(xiàng)目:http:///projects/tinybind

這一節(jié)展示了一種普通老式的方法來使用XML加載和保存一個(gè)基本的對象結(jié)構(gòu)。

建立你的對象類

從一些像這樣的基本類開始:

 

#include <string>
#include <map>
using namespace std;
 
typedef std::map<std::string,std::string> MessageMap;
 
// 基本的窗口抽象 - 僅僅是個(gè)示例
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);
    
    // 僅用于顯示它是如何工作的
    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;
    }
};

這是一個(gè)基本的mian(),它向我們展示了怎樣創(chuàng)建一個(gè)默認(rèn)的settings對象樹,怎樣保存并再次加載:

 

int main(void)
{
    AppSettings settings;
    
    settings.save("appsettings2.xml");
    settings.load("appsettings2.xml");
    return 0;
}

接下來的main()展示了如何創(chuàng)建,修改,保存和加載一個(gè)settings結(jié)構(gòu):

 

int main(void)
{
    // 區(qū)塊:定制并保存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");
    }
    
    // 區(qū)塊:加載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;
}

當(dāng)save()和load()完成后(請看下面),運(yùn)行這個(gè)main()就會在控制臺看到:

 

HitchHikerApp: Don’t Panic
HitchHikerApp: Show window ‘BookFrame’ at 15,25 (300 x 100)
HitchHikerApp: Thanks for all the fish

把C++狀態(tài)編碼成XML

有很多方法能夠做到把文檔對象保存到文件中,這就是其中一個(gè):

 

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->SetValue(s.c_str()); 
    root->LinkEndChild( comment ); 
    
    // 區(qū)塊:messages
    {
        MessageMap::iterator iter;
        
        TiXmlElement * msgs = new TiXmlElement( "Messages" ); 
        root->LinkEndChild( msgs ); 
        
        for (iter=m_messages.begin(); iter != m_messages.end(); iter++)
        {
            const string & key=(*iter).first;
            const string & value=(*iter).second;
            msg = new TiXmlElement(key.c_str()); 
            msg->LinkEndChild( new TiXmlText(value.c_str())); 
            msgs->LinkEndChild( msg ); 
        }
    }
    
    // 區(qū)塊:windows
    {
        TiXmlElement * windowsNode = new TiXmlElement( "Windows" ); 
        root->LinkEndChild( windowsNode ); 
        
        list<WindowSettings>::iterator iter;
        
        for (iter=m_windows.begin(); iter != m_windows.end(); iter++)
        {
            const WindowSettings& w=*iter;
            
            TiXmlElement * window;
            window = new TiXmlElement( "Window" ); 
            windowsNode->LinkEndChild( window ); 
            window->SetAttribute("name", w.name.c_str());
            window->SetAttribute("x", w.x);
            window->SetAttribute("y", w.y);
            window->SetAttribute("w", w.w);
            window->SetAttribute("h", w.h);
        }
    }
    
    // 區(qū)塊:connection
    {
        TiXmlElement * cxn = new TiXmlElement( "Connection" ); 
        root->LinkEndChild( cxn ); 
        cxn->SetAttribute("ip", m_connection.ip.c_str());
        cxn->SetDoubleAttribute("timeout", m_connection.timeout); 
    }
    
    doc.SaveFile(pFilename); 
}

用修改過的main運(yùn)行會生成這個(gè)文件:

 

<?xml version="1.0" ?>
<HitchHikerApp>
   <!– Settings for HitchHikerApp –>
   <Messages>
      <Farewell>Thanks for all the fish</Farewell>
      <Welcome>Don't Panic</Welcome>
   </Messages>
   <Windows>
      <Window name="BookFrame" x="15" y="25" w="300" h="250" />
   </Windows>
   <Connection ip="192.168.0.77" timeout="42.000000" />
</HitchHikerApp>

從XML中解碼出狀態(tài)

就像編碼一樣,也有許多方法可以讓你從自己的C++對象結(jié)構(gòu)中解碼出XML。下面的方法使用了TiXmlHandles。

 

void AppSettings::load(const char* pFilename)
{
    TiXmlDocument doc(pFilename);
    if (!doc.LoadFile()) return;
    
    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;
    TiXmlHandle hRoot(0);
    
    // 區(qū)塊:name
    {
        pElem=hDoc.FirstChildElement().Element();
        // 必須有一個(gè)合法的根結(jié)點(diǎn),如果沒有則溫文地處理(譯注:直接返回
        if (!pElem) return;
        m_name=pElem->Value();
        
        // 保存起來以備后面之用
        hRoot=TiXmlHandle(pElem);
    }
    
    // 區(qū)塊:string table
    {
        m_messages.clear(); // 清空已有的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;
            }
        }
    }
    
    // 區(qū)塊:windows
    {
        m_windows.clear(); // 清空鏈表
        
        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); // 如果失敗,原值保持現(xiàn)狀
            pWindowNode->QueryIntAttribute("y", &w.y);
            pWindowNode->QueryIntAttribute("w", &w.w);
            pWindowNode->QueryIntAttribute("hh", &w.h);
            
            m_windows.push_back(w);
        }
    }
    
    // 區(qū)塊:connection
    {
        pElem=hRoot.FirstChild("Connection").Element();
        if (pElem)
        {
            m_connection.ip=pElem->Attribute("ip");
            pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);
        }
    }
}

dump_to_stdout的完整列表

下面是一個(gè)可直接運(yùn)行的示例程序,使用上面提到過的遞歸遍歷方式,可用來加載任意的XML文件并把結(jié)構(gòu)輸出到STDOUT上。

 

// 指南示例程序
#include "stdafx.h"
#include "tinyxml.h"
 
// ———————————————————————-
// STDOUT輸出和縮進(jìn)實(shí)用函數(shù)
// ———————————————————————-
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 ];
}
 
// 與getIndent相同,但最后沒有“+”
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 );
    }
}
 
// 加載指定的文件并把它的結(jié)構(gòu)輸出到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 ); 
    }
    else
    {
        printf("Failed to load file \"%s\”\n", pFilename);
    }
}
 
// ———————————————————————-
// main(),打印出從命令行指定的文件
// ———————————————————————-
int main(int argc, char* argv[])
{
    for (int i=1; i<argc; i++)
    {
        dump_to_stdout(argv[i]);
    }
    return 0;
}

從命令行或者DOS窗口運(yùn)行它,例如:

 

C:\dev\tinyxml> Debug\tinyxml_1.exe example1.xml
example1.xml:
Document
+ Declaration
+ Element [Hello]
  (No attributes)
  + Text: [World]

作者與修改

  • Ellers寫于2005年4,5,6月
  • Lee Thomason于2005年9月略加編輯后集成到文檔系統(tǒng)中
  • Ellers于2005年10月做了更新

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多