免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1591 | 回复: 0
打印 上一主题 下一主题

TinyXML 指南 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-19 12:22 |只看该作者 |倒序浏览
TinyXML 指南
这是什么?
这份指南有一些关于如何有效地使用TinyXML的技巧和建议。
我也会尝试讲一些诸如怎样使字符串与整型数相互转化的C++技巧。这与TinyXML本身没什么关系,但它也许会对你的项目有所帮助,所以我还是把它加进来了。
如果你不知道基本的C++概念,那么这份指南就没什么用了。同样的,如果你不知道什么是DOM,那先从其它地方找来看看吧。
在我们开始之前
一些将会被用到的XML数据集/文件。
example1.xml:
World
example2.xml:
   
        Alas
           Great World
              Alas (again)
   
example3.xml:
   
   
example4.xml:
   
   
      Welcome to MyApp
      Thank you for using MyApp
   
   
      
   
   
开始
把文件加载成XML
把一个文件加载成TinyXML DOM的最简单方法是:
TiXmlDocument doc( [color="#ff00ff"]"demo.xml" );
doc.LoadFile();
一个更接近于现实应用的例子如下。它加载文件并把内容显示到标准输出STDOUT上:
[color="#008000"]// 加载指定的文件并把它的结构输出到STDOUT上
[color="#0000ff"]void dump_to_stdout(const [color="#0000ff"]char* pFilename)
{
    TiXmlDocument doc(pFilename);
    [color="#0000ff"]bool loadOkay = doc.LoadFile();
    [color="#0000ff"]if (loadOkay)
    {
        printf([color="#ff00ff"]"\n%s:\n", pFilename);
        dump_to_stdout( &doc ); [color="#008000"]// 稍后在指南中定义
    }
    [color="#0000ff"]else
    {
        printf([color="#ff00ff"]"Failed to load file \"%s\”\n", pFilename);
    }
}
在main中使用此函数的一个简单应用示范如下:
[color="#0000ff"]int main([color="#0000ff"]void)
{
    dump_to_stdout([color="#ff00ff"]"example1.xml");
    [color="#0000ff"]return 0;
}
回想example1的XML:
World
用这个XML运行程序就会在控制台/DOS窗口中显示:
DOCUMENT
  + DECLARATION
  + ELEMENT Hello
    + TEXT[World]
”dump_to_stdout“函数稍后会在这份指南中定义,如果你想要理解怎样递归遍历一个DOM它会很有用。
用程序建立文档对象
这是用程序建立example1的方法:
[color="#0000ff"]void build_simple_doc( )
{
    [color="#008000"]// 生成xml: World
    TiXmlDocument doc;
    TiXmlDeclaration * decl = [color="#0000ff"]new TiXmlDeclaration( [color="#ff00ff"]"1.0", [color="#ff00ff"]"", [color="#ff00ff"]"" );
    TiXmlElement * element = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Hello" );
    TiXmlText * text = [color="#0000ff"]new TiXmlText( [color="#ff00ff"]"World" );
    element->LinkEndChild( text );
    doc.LinkEndChild( decl );
    doc.LinkEndChild( element );
    doc.SaveFile( [color="#ff00ff"]"madeByHand.xml" );
}
然后可以用以下方法加载并显示在控制台上:
dump_to_stdout([color="#ff00ff"]"madeByHand.xml"); [color="#008000"]// 此函数稍后会中指南中定义
你会看到跟example1一模一样:
madeByHand.xml:
  Document
  + Declaration
  + Element [Hello]
    + Text: [World]
这段代码会产生相同的XML DOM,但它以不同的顺序来创建和链接结点:
[color="#0000ff"]void write_simple_doc2( )
{
    [color="#008000"]// 实现与 write_simple_doc1一样的功能,(译注:我想它指是build_simple_doc)
    [color="#008000"]// 但尽可能早地把结点添加到树中。
    TiXmlDocument doc;
    TiXmlDeclaration * decl = [color="#0000ff"]new TiXmlDeclaration( [color="#ff00ff"]"1.0", [color="#ff00ff"]"", [color="#ff00ff"]"" );
    doc.LinkEndChild( decl );
   
    TiXmlElement * element = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Hello" );
    doc.LinkEndChild( element );
   
    TiXmlText * text = [color="#0000ff"]new TiXmlText( [color="#ff00ff"]"World" );
    element->LinkEndChild( text );
   
    doc.SaveFile( [color="#ff00ff"]"madeByHand2.xml" );
}
两个都产生同样的XML,即:
World
结构构成都是:
DOCUMENT
  + DECLARATION
  + ELEMENT Hello
    + TEXT[World]
属性
给定一个存在的结点,设置它的属性是很容易的:
window = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Demo" );
window->SetAttribute([color="#ff00ff"]"name", [color="#ff00ff"]"Circle");
window->SetAttribute([color="#ff00ff"]"x", 5);
window->SetAttribute([color="#ff00ff"]"y", 15);
window->SetDoubleAttribute([color="#ff00ff"]"radius", 3.14159);
你也可以用TiXmlAttribute对象达到同样的目的。
下面的代码向我们展示了一种(并不只有一种)获取某一元素属性并打印出它们的名字和字符串值的方法,如果值能够被转化为整型数或者浮点数,也把值打印出来:
[color="#008000"]// 打印pElement的所有属性。
[color="#008000"]// 返回已打印的属性数量。
[color="#0000ff"]int dump_attribs_to_stdout(TiXmlElement* pElement, [color="#0000ff"]unsigned [color="#0000ff"]int indent)
{
    [color="#0000ff"]if ( !pElement ) [color="#0000ff"]return 0;
   
    TiXmlAttribute* pAttrib=pElement->FirstAttribute();
    [color="#0000ff"]int i=0;
    [color="#0000ff"]int ival;
    [color="#0000ff"]double dval;
    const [color="#0000ff"]char* pIndent=getIndent(indent);
    printf([color="#ff00ff"]"\n");
    [color="#0000ff"]while (pAttrib)
    {
        printf( [color="#ff00ff"]"%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());
        
        [color="#0000ff"]if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( [color="#ff00ff"]" int=%d", ival);
        [color="#0000ff"]if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( [color="#ff00ff"]" d=%1.1f", dval);
        printf( [color="#ff00ff"]"\n" );
        i++;
        pAttrib=pAttrib->Next();
    }
    [color="#0000ff"]return i;
}
把文档对象写到文件中
把一个已经建立好的DOM写到文件中是非常简单的:
doc.SaveFile( saveFilename );
回想一下,比如example4:
   
   
      Welcome to MyApp
      Thank you for using MyApp
   
   
      
   
   
以下函数建立这个DOM并把它写到“appsettings.xml”文件中:
[color="#0000ff"]void write_app_settings_doc( )
{
    TiXmlDocument doc;
    TiXmlElement* msg;
    TiXmlDeclaration* decl = [color="#0000ff"]new TiXmlDeclaration( [color="#ff00ff"]"1.0", [color="#ff00ff"]"", [color="#ff00ff"]"" );
    doc.LinkEndChild( decl );
   
    TiXmlElement * root = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"MyApp" );
    doc.LinkEndChild( root );
   
    TiXmlComment * comment = [color="#0000ff"]new TiXmlComment();
    comment->SetValue([color="#ff00ff"]" Settings for MyApp " );
    root->LinkEndChild( comment );
   
    TiXmlElement * msgs = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Messages" );
    root->LinkEndChild( msgs );
   
    msg = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Welcome" );
    msg->LinkEndChild( [color="#0000ff"]new TiXmlText( [color="#ff00ff"]"Welcome to MyApp" ));
    msgs->LinkEndChild( msg );
   
    msg = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Farewell" );
    msg->LinkEndChild( [color="#0000ff"]new TiXmlText( [color="#ff00ff"]"Thank you for using MyApp" ));
    msgs->LinkEndChild( msg );
   
    TiXmlElement * windows = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Windows" );
    root->LinkEndChild( windows );
   
    TiXmlElement * window;
    window = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Window" );
    windows->LinkEndChild( window );
    window->SetAttribute([color="#ff00ff"]"name", [color="#ff00ff"]"MainFrame");
    window->SetAttribute([color="#ff00ff"]"x", 5);
    window->SetAttribute([color="#ff00ff"]"y", 15);
    window->SetAttribute([color="#ff00ff"]"w", 400);
    window->SetAttribute([color="#ff00ff"]"h", 250);
   
    TiXmlElement * cxn = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Connection" );
    root->LinkEndChild( cxn );
    cxn->SetAttribute([color="#ff00ff"]"ip", [color="#ff00ff"]"192.168.0.1");
    cxn->SetDoubleAttribute([color="#ff00ff"]"timeout", 123.456); [color="#008000"]// 浮点数属性
   
    dump_to_stdout( &doc );
    doc.SaveFile( [color="#ff00ff"]"appsettings.xml" );
}
dump_to_stdout函数将显示如下结构:
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默认以其它APIs称作“pretty”格式的方式来输出XML,对此我感到惊讶。这种格式修改了元素的文本结点中的空格,以使输出来的结点树包含一个嵌套层标记。
我还没有仔细看当写到一个文件中时是否有办法关闭这种缩进——这肯定很容易做到。(译注:这两句话大概是Ellers说的)
[Lee:在STL模式下这很容易做到,只需要cout XML与C++对象的相互转化
介绍
这个例子假设你在用一个XML文件来加载和保存你的应用程序配置,举例来说,有点像example4.xml。
有许多方法可以做到这点。例如,看看TinyBind项目:
http://sourceforge.net/projects/tinybind

这一节展示了一种普通老式的方法来使用XML加载和保存一个基本的对象结构。
建立你的对象类
从一些像这样的基本类开始:
[color="#ff0000"]#include
[color="#ff0000"]#include
[color="#0000ff"]using [color="#0000ff"]namespace [color="#0000ff"]std;

[color="#0000ff"]typedef [color="#0000ff"]std::map MessageMap;

[color="#008000"]// 基本的窗口抽象 - 仅仅是个示例
[color="#0000ff"]class WindowSettings
{
    [color="#0000ff"]public:
    [color="#0000ff"]int x,y,w,h;
    [color="#0000ff"]string name;
   
    WindowSettings()
        : x(0), y(0), w(100), h(100), name([color="#ff00ff"]"Untitled")
    {
    }
   
    WindowSettings([color="#0000ff"]int x, [color="#0000ff"]int y, [color="#0000ff"]int w, [color="#0000ff"]int h, const [color="#0000ff"]string& name)
    {
        [color="#0000ff"]this->x=x;
        [color="#0000ff"]this->y=y;
        [color="#0000ff"]this->w=w;
        [color="#0000ff"]this->h=h;
        [color="#0000ff"]this->name=name;
    }
};
 
[color="#0000ff"]class ConnectionSettings
{
    [color="#0000ff"]public:
    [color="#0000ff"]string [color="#808000"]ip;
    [color="#0000ff"]double timeout;
};

[color="#0000ff"]class AppSettings
{
    [color="#0000ff"]public:
    [color="#0000ff"]string m_name;
    MessageMap m_messages;
    [color="#0000ff"]list m_windows;
    ConnectionSettings m_connection;
   
    AppSettings() {}
   
    [color="#0000ff"]void save(const [color="#0000ff"]char* pFilename);
    [color="#0000ff"]void load(const [color="#0000ff"]char* pFilename);
   
    [color="#008000"]// 仅用于显示它是如何工作的
    [color="#0000ff"]void setDemoValues()
    {
        m_name=[color="#ff00ff"]"MyApp";
        m_messages.clear();
        m_messages[[color="#ff00ff"]"Welcome"]=[color="#ff00ff"]"Welcome to "+m_name;
        m_messages[[color="#ff00ff"]"Farewell"]=[color="#ff00ff"]"Thank you for using "+m_name;
        m_windows.clear();
        m_windows.push_back(WindowSettings(15,15,400,250,[color="#ff00ff"]"Main"));
        m_connection.ip=[color="#ff00ff"]"Unknown";
        m_connection.timeout=123.456;
    }
};
这是一个基本的mian(),它向我们展示了怎样创建一个默认的settings对象树,怎样保存并再次加载:
[color="#0000ff"]int main([color="#0000ff"]void)
{
    AppSettings settings;
   
    settings.save([color="#ff00ff"]"appsettings2.xml");
    settings.load([color="#ff00ff"]"appsettings2.xml");
    [color="#0000ff"]return 0;
}
接下来的main()展示了如何创建,修改,保存和加载一个settings结构:
[color="#0000ff"]int main([color="#0000ff"]void)
{
    [color="#008000"]// 区块:定制并保存settings
    {
        AppSettings settings;
        settings.m_name=[color="#ff00ff"]"HitchHikerApp";
        settings.m_messages[[color="#ff00ff"]"Welcome"]=[color="#ff00ff"]"Don’t Panic";
        settings.m_messages[[color="#ff00ff"]"Farewell"]=[color="#ff00ff"]"Thanks for all the fish";
        settings.m_windows.push_back(WindowSettings(15,25,300,250,[color="#ff00ff"]"BookFrame"));
        settings.m_connection.ip=[color="#ff00ff"]"192.168.0.77";
        settings.m_connection.timeout=42.0;
        
        settings.save([color="#ff00ff"]"appsettings2.xml");
    }
   
    [color="#008000"]// 区块:加载settings
    {
        AppSettings settings;
        settings.load([color="#ff00ff"]"appsettings2.xml");
        printf([color="#ff00ff"]"%s: %s\n", settings.m_name.c_str(),
        settings.m_messages[[color="#ff00ff"]"Welcome"].c_str());
        WindowSettings & w=settings.m_windows.front();
        printf([color="#ff00ff"]"%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([color="#ff00ff"]"%s: %s\n", settings.m_name.c_str(),
                           settings.m_messages[[color="#ff00ff"]"Farewell"].c_str());
    }
    [color="#0000ff"]return 0;
}
当save()和load()完成后(请看下面),运行这个main()就会在控制台看到:
HitchHikerApp: Don’t Panic
  HitchHikerApp: Show window ‘BookFrame’ at 15,25 (300 x 100)
  HitchHikerApp: Thanks for all the fish
把C++状态编码成XML
有很多方法能够做到把文档对象保存到文件中,这就是其中一个:
[color="#0000ff"]void AppSettings::save(const [color="#0000ff"]char* pFilename)
{
    TiXmlDocument doc;
    TiXmlElement* msg;
    TiXmlComment * comment;
    [color="#0000ff"]string s;
    TiXmlDeclaration* decl = [color="#0000ff"]new TiXmlDeclaration( [color="#ff00ff"]"1.0", [color="#ff00ff"]"", [color="#ff00ff"]"" );
    doc.LinkEndChild( decl );
   
    TiXmlElement * root = [color="#0000ff"]new TiXmlElement(m_name.c_str());
    doc.LinkEndChild( root );
   
    comment = [color="#0000ff"]new TiXmlComment();
    s=[color="#ff00ff"]" Settings for "+m_name+[color="#ff00ff"]" ";
    comment->SetValue(s.c_str());
    root->LinkEndChild( comment );
   
    [color="#008000"]// 区块:messages
    {
        MessageMap::iterator iter;
        
        TiXmlElement * msgs = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Messages" );
        root->LinkEndChild( msgs );
        
        [color="#0000ff"]for (iter=m_messages.begin(); iter != m_messages.end(); iter++)
        {
            const [color="#0000ff"]string & key=(*iter).first;
            const [color="#0000ff"]string & value=(*iter).second;
            msg = [color="#0000ff"]new TiXmlElement(key.c_str());
            msg->LinkEndChild( [color="#0000ff"]new TiXmlText(value.c_str()));
            msgs->LinkEndChild( msg );
        }
    }
   
    [color="#008000"]// 区块:windows
    {
        TiXmlElement * windowsNode = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Windows" );
        root->LinkEndChild( windowsNode );
        
        [color="#0000ff"]list::iterator iter;
        
        [color="#0000ff"]for (iter=m_windows.begin(); iter != m_windows.end(); iter++)
        {
            const WindowSettings& w=*iter;
            
            TiXmlElement * window;
            window = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Window" );
            windowsNode->LinkEndChild( window );
            window->SetAttribute([color="#ff00ff"]"name", w.name.c_str());
            window->SetAttribute([color="#ff00ff"]"x", w.x);
            window->SetAttribute([color="#ff00ff"]"y", w.y);
            window->SetAttribute([color="#ff00ff"]"w", w.w);
            window->SetAttribute([color="#ff00ff"]"h", w.h);
        }
    }
   
    [color="#008000"]// 区块:connection
    {
        TiXmlElement * cxn = [color="#0000ff"]new TiXmlElement( [color="#ff00ff"]"Connection" );
        root->LinkEndChild( cxn );
        cxn->SetAttribute([color="#ff00ff"]"ip", m_connection.ip.c_str());
        cxn->SetDoubleAttribute([color="#ff00ff"]"timeout", m_connection.timeout);
    }
   
    doc.SaveFile(pFilename);
}
用修改过的main运行会生成这个文件:
   
   
      Thanks for all the fish
      Don't Panic
   
   
      
   
   
从XML中解码出状态
就像编码一样,也有许多方法可以让你从自己的C++对象结构中解码出XML。下面的方法使用了TiXmlHandles。
[color="#0000ff"]void AppSettings::load(const [color="#0000ff"]char* pFilename)
{
    TiXmlDocument doc(pFilename);
    [color="#0000ff"]if (!doc.LoadFile()) [color="#0000ff"]return;
   
    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;
    TiXmlHandle hRoot(0);
   
    [color="#008000"]// 区块:name
    {
        pElem=hDoc.FirstChildElement().Element();
        [color="#008000"]// 必须有一个合法的根结点,如果没有则温文地处理(译注:直接返回)
        [color="#0000ff"]if (!pElem) [color="#0000ff"]return;
        m_name=pElem->Value();
        
        [color="#008000"]// 保存起来以备后面之用
        hRoot=TiXmlHandle(pElem);
    }
   
    [color="#008000"]// 区块:string table
    {
        m_messages.clear(); [color="#008000"]// 清空已有的table
        
        pElem=hRoot.FirstChild( [color="#ff00ff"]"Messages" ).FirstChild().Element();
        [color="#0000ff"]for( pElem; pElem; pElem=pElem->NextSiblingElement())
        {
            const [color="#0000ff"]char *pKey=pElem->Value();
            const [color="#0000ff"]char *pText=pElem->GetText();
            [color="#0000ff"]if (pKey && pText)
            {
                m_messages[pKey]=pText;
            }
        }
    }
   
    [color="#008000"]// 区块:windows
    {
        m_windows.clear(); [color="#008000"]// 清空链表
        
        TiXmlElement* pWindowNode=hRoot.FirstChild( [color="#ff00ff"]"Windows" )
                                       .FirstChild().Element();
        [color="#0000ff"]for( pWindowNode; pWindowNode;
             pWindowNode=pWindowNode->NextSiblingElement())
        {
            WindowSettings w;
            const [color="#0000ff"]char *pName=pWindowNode->Attribute([color="#ff00ff"]"name");
            [color="#0000ff"]if (pName) w.name=pName;
            
            pWindowNode->QueryIntAttribute([color="#ff00ff"]"x", &w.x); [color="#008000"]// 如果失败,原值保持现状
            pWindowNode->QueryIntAttribute([color="#ff00ff"]"y", &w.y);
            pWindowNode->QueryIntAttribute([color="#ff00ff"]"w", &w.w);
            pWindowNode->QueryIntAttribute([color="#ff00ff"]"hh", &w.h);
            
            m_windows.push_back(w);
        }
    }
   
    [color="#008000"]// 区块:connection
    {
        pElem=hRoot.FirstChild([color="#ff00ff"]"Connection").Element();
        [color="#0000ff"]if (pElem)
        {
            m_connection.ip=pElem->Attribute([color="#ff00ff"]"ip");
            pElem->QueryDoubleAttribute([color="#ff00ff"]"timeout",&m_connection.timeout);
        }
    }
}
dump_to_stdout的完整列表
下面是一个可直接运行的示例程序,使用上面提到过的递归遍历方式,可用来加载任意的XML文件并把结构输出到STDOUT上。
[color="#008000"]// 指南示例程序
[color="#ff0000"]#include [color="#ff00ff"]"stdafx.h"
[color="#ff0000"]#include [color="#ff00ff"]"tinyxml.h"

[color="#008000"]// ———————————————————————-
[color="#008000"]// STDOUT输出和缩进实用函数
[color="#008000"]// ———————————————————————-
const [color="#0000ff"]unsigned [color="#0000ff"]int NUM_INDENTS_PER_SPACE=2;

const [color="#0000ff"]char * getIndent( [color="#0000ff"]unsigned [color="#0000ff"]int numIndents )
{
    [color="#0000ff"]static const [color="#0000ff"]char * pINDENT=[color="#ff00ff"]" + ";
    [color="#0000ff"]static const [color="#0000ff"]unsigned [color="#0000ff"]int LENGTH=strlen( pINDENT );
    [color="#0000ff"]unsigned [color="#0000ff"]int n=numIndents*NUM_INDENTS_PER_SPACE;
    [color="#0000ff"]if ( n > LENGTH ) n = LENGTH;
   
    [color="#0000ff"]return &pINDENT[ LENGTH-n ];
}

[color="#008000"]// 与getIndent相同,但最后没有“+”
const [color="#0000ff"]char * getIndentAlt( [color="#0000ff"]unsigned [color="#0000ff"]int numIndents )
{
    [color="#0000ff"]static const [color="#0000ff"]char * pINDENT=[color="#ff00ff"]" ";
    [color="#0000ff"]static const [color="#0000ff"]unsigned [color="#0000ff"]int LENGTH=strlen( pINDENT );
    [color="#0000ff"]unsigned [color="#0000ff"]int n=numIndents*NUM_INDENTS_PER_SPACE;
    [color="#0000ff"]if ( n > LENGTH ) n = LENGTH;
   
    [color="#0000ff"]return &pINDENT[ LENGTH-n ];
}

[color="#0000ff"]int dump_attribs_to_stdout(TiXmlElement* pElement, [color="#0000ff"]unsigned [color="#0000ff"]int indent)
{
    [color="#0000ff"]if ( !pElement ) [color="#0000ff"]return 0;
   
    TiXmlAttribute* pAttrib=pElement->FirstAttribute();
    [color="#0000ff"]int i=0;
    [color="#0000ff"]int ival;
    [color="#0000ff"]double dval;
    const [color="#0000ff"]char* pIndent=getIndent(indent);
    printf([color="#ff00ff"]"\n");
    [color="#0000ff"]while (pAttrib)
    {
        printf( [color="#ff00ff"]"%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());
        
        [color="#0000ff"]if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( [color="#ff00ff"]" int=%d", ival);
        [color="#0000ff"]if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( [color="#ff00ff"]" d=%1.1f", dval);
        printf( [color="#ff00ff"]"\n" );
        i++;
        pAttrib=pAttrib->Next();
    }
    [color="#0000ff"]return i;
}

[color="#0000ff"]void dump_to_stdout( TiXmlNode* pParent, [color="#0000ff"]unsigned [color="#0000ff"]int indent = 0 )
{
    [color="#0000ff"]if ( !pParent ) [color="#0000ff"]return;
   
    TiXmlNode* pChild;
    TiXmlText* pText;
    [color="#0000ff"]int t = pParent->Type();
    printf( [color="#ff00ff"]"%s", getIndent(indent));
    [color="#0000ff"]int num;
   
    [color="#0000ff"]switch ( t )
    {
        [color="#0000ff"]case TiXmlNode::DOCUMENT:
            printf( [color="#ff00ff"]"Document" );
            [color="#0000ff"]break;
        
        [color="#0000ff"]case TiXmlNode::ELEMENT:
            printf( [color="#ff00ff"]"Element [%s]", pParent->Value() );
            num=dump_attribs_to_stdout(pParent->ToElement(), indent+1);
            [color="#0000ff"]switch(num)
            {
                [color="#0000ff"]case 0: printf( [color="#ff00ff"]" (No attributes)"); [color="#0000ff"]break;
                [color="#0000ff"]case 1: printf( [color="#ff00ff"]"%s1 attribute", getIndentAlt(indent)); [color="#0000ff"]break;
                [color="#0000ff"]default: printf( [color="#ff00ff"]"%s%d attributes", getIndentAlt(indent), num); [color="#0000ff"]break;
            }
            [color="#0000ff"]break;
        
        [color="#0000ff"]case TiXmlNode::COMMENT:
            printf( [color="#ff00ff"]"Comment: [%s]", pParent->Value());
            [color="#0000ff"]break;
        
        [color="#0000ff"]case TiXmlNode::UNKNOWN:
            printf( [color="#ff00ff"]"Unknown" );
            [color="#0000ff"]break;
        
        [color="#0000ff"]case TiXmlNode::TEXT:
            pText = pParent->ToText();
            printf( [color="#ff00ff"]"Text: [%s]", pText->Value() );
            [color="#0000ff"]break;
        
        [color="#0000ff"]case TiXmlNode::DECLARATION:
            printf( [color="#ff00ff"]"Declaration" );
            [color="#0000ff"]break;
            [color="#0000ff"]default:
            [color="#0000ff"]break;
    }
    printf( [color="#ff00ff"]"\n" );
    [color="#0000ff"]for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
    {
        dump_to_stdout( pChild, indent+1 );
    }
}

[color="#008000"]// 加载指定的文件并把它的结构输出到STDOUT上
[color="#0000ff"]void dump_to_stdout(const [color="#0000ff"]char* pFilename)
{
    TiXmlDocument doc(pFilename);
    [color="#0000ff"]bool loadOkay = doc.LoadFile();
    [color="#0000ff"]if (loadOkay)
    {
        printf([color="#ff00ff"]"\n%s:\n", pFilename);
        dump_to_stdout( &doc );
    }
    [color="#0000ff"]else
    {
        printf([color="#ff00ff"]"Failed to load file \"%s\”\n", pFilename);
    }
}

[color="#008000"]// ———————————————————————-
[color="#008000"]// main(),打印出从命令行指定的文件
[color="#008000"]// ———————————————————————-
[color="#0000ff"]int main([color="#0000ff"]int argc, [color="#0000ff"]char* argv[])
{
    [color="#0000ff"]for ([color="#0000ff"]int i=1; iC:\dev\tinyxml> Debug\tinyxml_1.exe example1.xml
  example1.xml:
  Document
  + Declaration
  + Element [Hello]
    (No attributes)
    + Text: [World]


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/102400/showart_2031563.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP