C++使用TinyXML解析XML
1.介紹
Tinyxml的官方網(wǎng)址:http://www.grinninglizard.com
官方介紹文檔:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html
在TinyXML中,根據(jù)XML的各種元素來定義了一些類:
- TiXmlBase:整個TinyXML模型的基類。
- TiXmlAttribute:對應(yīng)于XML中的元素的屬性。
- TiXmlNode:對應(yīng)于DOM結(jié)構(gòu)中的節(jié)點(diǎn)。
- TiXmlComment:對應(yīng)于XML中的注釋
- TiXmlDeclaration:對應(yīng)于XML中的申明部分,即<?versiong="1.0" ?>。
- TiXmlDocument:對應(yīng)于XML的整個文檔。
- TiXmlElement:對應(yīng)于XML的元素。
- TiXmlText:對應(yīng)于XML的文字部分
- TiXmlUnknown:對應(yīng)于XML的未知部分。
- TiXmlHandler:定義了針對XML的一些操作。
根據(jù)下圖來說明常用的類對應(yīng)的文本格式:
<?xml version="1.0" ?> //TiXmlDeclaration,聲明
<MyApp> //TiXmlElement,元素
<!-- Settings for MyApp -->//TiXmlComment,注釋
<Messages>//TiXmlElement,元素
<Welcome>Welcome to MyApp</Welcome>
//<Welcome>是元素TiXmlElement ,“Welcome to MyApp”是TiXmlText,文本
<Farewell>Thank you for using MyApp</Farewell>//同上
</Messages>
<Windows>//TiXmlElement,元素
<Window name="MainFrame" x="5" y="15" w="400" h="250" />
// Window是元素TiXmlElement ,name、x、y、h是TiXmlAttribute
</Windows>
<Connection ip="192.168.0.1" timeout="123.456000" />
</MyApp>
TinyXML是個解析庫,主要由DOM模型類(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作類(TiXmlHandler)構(gòu)成。它由兩個頭文件(.h文件)和四個CPP文件(.cpp文件)構(gòu)成,用的時候,只要將(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)導(dǎo)入工程就可以用它的東西了。如果需要,可以將它做成自己的DLL來調(diào)用。
注意,TiXmlBase 是TiXmlNode的基類,TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基類。
2.TinyXML配置
在stdafx.h頭文件中增加頭文件引用#include "tinyxml/tinyxml.h"
在工程設(shè)置中加入lib引用庫
在stdafx.h中加入動態(tài)庫引用
#ifdef _DEBUG #pragma comment(lib,"TinyXMLD.lib") #else #pragma comment(lib,"TinyXML.lib") #endif
3.TinyXML讀取和保存文件
3.1 讀取xml文件
TiXmlDocument lconfigXML;
if( !lconfigXML.LoadFile( strXmlFile.c_str() ) )
{
break;
}
3.2 讀取xml參數(shù)
TiXmlDocument lActionXML;
lActionXML.Parse(strRmcpParam.c_str());
if(lActionXML.Error())
{
strErr = "輸入?yún)?shù)不是標(biāo)準(zhǔn)的xml格式";
return false;
}
3.3 保存xml參數(shù)到文本
TiXmlDocument tyDoc; … tyDoc.SaveFile(m_strFilePath);
3.4 保存xml參數(shù)到臨時變量
TiXmlDocument tyDoc; … TiXmlPrinter printer; tyDoc.Accept(&printer); std::string devParam = std::string(printer.CStr());
4.TinyXML增刪改查
4.1 增
創(chuàng)建一個如1中的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); // floating point attrib
dump_to_stdout( &doc );
doc.SaveFile( "appsettings.xml" );
}
在節(jié)點(diǎn)最后插入新節(jié)點(diǎn)
TiXmlNode* LinkEndChild( TiXmlNode* addThis );
在節(jié)點(diǎn)后 前/后 插入新節(jié)點(diǎn)
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
4.2 刪
刪除某個節(jié)點(diǎn), TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基類
TiXmlNode node; node.Clear();
從A節(jié)點(diǎn)上移除子節(jié)點(diǎn)B
TiXmlNode nodeA; nodeA. RemoveChild( TiXmlNode* removeThis );
從元素A上移除名字為B的屬性
TiXmlAttribute attrA; attrA. RemoveAttribute( const char * name );
4.3 改
查找內(nèi)容為<mfid val="1234" />,現(xiàn)需要將1234改成其他值
TiXmlNode* lpnode = NULL;
lpnode = tixml.RootElement()->IterateChildren("mfid",lpnode);
TiXmlAttribute* tiattr = lpnode->ToElement()->FirstAttribute();
//找到mfid節(jié)點(diǎn),獲取第一個屬性值。注意,如果有多個屬性值,需要判斷哪個屬性值是需要的
tiattr->SetValue(mfid.c_str());
替換一個節(jié)點(diǎn)
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
4.4 查
獲取link節(jié)點(diǎn)
const TiXmlNode* lpItemNode = NULL;//初始化
lpItemNode = lconfigXML.RootElement()->IterateChildren("link", lpItemNode);
if (lpItemNode == NULL)
{
//Can not find <link>break;
}
獲取link節(jié)點(diǎn)中的type屬性值
std::string strType = lpItemNode->ToElement()->Attribute("type");
遍歷節(jié)點(diǎn)
const TiXmlNode* lpMapNode = NULL; //初始化
lpMapNode = lconfigXML.RootElement()->IterateChildren("node", lpMapNode);
if (lpMapNode)
{
rms::CStationMapping litem;
const TiXmlNode* lpItemNode = NULL ;
while(lpItemNode = lpMapNode->IterateChildren("item",lpItemNode))
{
string str = lpItemNode->ToElement()->Attribute("ABC");
}
}
遍歷元素屬性
TiXmlAttribute* pAttr = NULL;
for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())
{
…
}
節(jié)點(diǎn)的下一個兄弟節(jié)點(diǎn)
const TiXmlNode* NextSibling() const;
元素的下一個元素
const TiXmlElement* NextSiblingElement() const;
屬性的下一個屬性
const TiXmlAttribute* Next() const;
返回值為NULL表示不存在
5.一個完整例子
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);
}
}
}
到此這篇關(guān)于C++使用TinyXML解析XML的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
構(gòu)造函數(shù)定義為private或者protected的好處
從語法上來講,一個函數(shù)被聲明為protected或者private,那么這個函數(shù)就不能從“外部”直接被調(diào)用了。對于protected的函數(shù),子類的“內(nèi)部”的其他函數(shù)可以調(diào)用之。而對于private的函數(shù),只能被本類“內(nèi)部”的其他函數(shù)說調(diào)用2013-10-10
詳解C語言中fseek函數(shù)和ftell函數(shù)的使用方法
這篇文章主要介紹了C語言中fseek函數(shù)和ftell函數(shù)的使用方法,兩個函數(shù)分別用于設(shè)置和返回文件指針stream的位置,需要的朋友可以參考下2016-03-03
C++?STL標(biāo)準(zhǔn)庫之std::list使用介紹及用法詳解
std::list是支持常數(shù)時間從容器任何位置插入和移除元素的容器,下面這篇文章主要給大家介紹了關(guān)于C++?STL標(biāo)準(zhǔn)庫之std::list使用介紹及用法詳解的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
vc中float與DWORD的互想轉(zhuǎn)換實(shí)現(xiàn)代碼
這篇文章主要介紹了vc中float與DWORD的互想轉(zhuǎn)換實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-06-06

