tinyxml学习一
在TinyXML中,根據XML的各種元素來定義了一些類:
??????? TiXmlBase:整個TinyXML模型的基類。
????????TiXmlAttribute:對應于XML中的元素的屬性。
????????TiXmlNode:對應于DOM結構中的節點。
????????TiXmlComment:對應于XML中的注釋。
????????TiXmlDeclaration:對應于XML中的申明部分,即<?versiong="1.0" ?>。
????????TiXmlDocument:對應于XML的整個文檔。
????????TiXmlElement:對應于XML的元素。
????????TiXmlText:對應于XML的文字部分。
????????TiXmlUnknown:對應于XML的未知部分。?
??????? TiXmlHandler:定義了針對XML的一些操作。
例如:
<!–?Our?to?do?list?data?–>
<ToDo>
<Item?priority="1">?Go?to?the?<bold>Toy?store!</bold></Item>
<Item?priority="2">?Do?bills</Item>
</ToDo>?
整個對象樹:?
TiXmlDocument "demo.xml"
TiXmlDeclaration "version=’1.0′" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills"?
在tinyXML中,用FirstChild("名字")查找節點時,調用FirstChild函數的節點與要查找的節點必須成“父子關系”。
句柄
想要健壯地讀取一個XML文檔,檢查方法調用后的返回值是否為null是很重要的。一種安全的檢錯實現可能會產生像這樣的代碼:?
?
TiXmlElement*?root?=?document.FirstChildElement(?"Document"?);if?(?root?)
{
TiXmlElement*?element?=?root->FirstChildElement(?"Element"?);
if?(?element?)
{
TiXmlElement*?child?=?element->FirstChildElement(?"Child"?);
if?(?child?)
{
TiXmlElement*?child2?=?child->NextSiblingElement(?"Child"?);
if?(?child2?)
{
//?Finally?do?something?useful.?
用句柄的話就不會這么冗長了,使用TiXmlHandle類,前面的代碼就會變成這樣:?
TiXmlElement*?child2?=?docHandle.FirstChild(?"Document"?).FirstChild(?"Element"?).Child(?"Child",?1?).ToElement();
if?(?child2?)
{
//?do?something?useful?
一、讀取XML,設置節點文本
如下XML片段:
<? xml?version="1.0"?encoding="UTF-8"?standalone="yes"? ?>
< ZXML >
???? < ZAPP >
????????? < VBS_RUNTIME_PARAMS >
??????????????? < BROADCAST_VERSION? info ="版本" >8 </ BROADCAST_VERSION >
??????????????? < Broadcast >
???????????????? < FileCount? info ="資源文件個數" >69 </ FileCount >
???????????????? < SOURCE_1 >
???????????????????? < ID? info ="圖片編號" >1 </ ID >
???????????????????? < Version? info ="圖片版本" >1 </ Version >
???????????????????? < Path? info ="圖片路徑" >/mnt/share/1.bmp </ Path >
???????????????????? < FileMode? info ="文件處理模式" >0 </ FileMode >
???????????????? </ SOURCE_1 >
???????????????? < SOURCE_2 >
???????????????????? < Path? info ="圖片路徑" >/mnt/share/2.bmp </ Path >
???????????????????? < ID? info ="圖片編號" >2 </ ID >
???????????????????? < Version? info ="圖片版本" >1 </ Version >
???????????????????? < FileMode? info ="文件處理模式" >0 </ FileMode >
???????????????? </ SOURCE_2 >
???????????????? .
???????????????? </ Broadcast >
????????? </ VBS_RUNTIME_PARAMS >
???? </ ZAPP >
</ ZXML >
要設置BROADCAST_VERSION節點的值 8為其他值,可參考如下代碼(將值加1):
用ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )方法替換
????TiXmlDocument?doc("zapp.conf");
????doc.LoadFile();
????TiXmlHandle?docHandle(?&doc?);
TiXmlElement*?Broadcast_ver?=?docHandle.FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChildElement("BROADCAST_VERSION").ToElement();
????TiXmlNode?*?oldnode?=??Broadcast_ver->FirstChild();
???? const? char?*ver?=?Broadcast_ver->GetText();
???? int?oldVer?=?atoi(ver);
????CString?newVer;
????newVer.Format("%d",oldVer+1);
????TiXmlText?newText(newVer);
????Broadcast_ver->ReplaceChild(oldnode,newText);
??? AfxMessageBox(Broadcast_ver->GetText()); // 輸出值
????doc.SaveFile();
二,刪除節點,屬性值
RemoveChild( TiXmlNode* removeThis )方法刪除父節點的子節點,
RemoveAttribute( const char * name )方法刪除屬性值.
例如刪除BROADCAST_VERSION節點
TiXmlHandle?docHandle(?&doc?);
????TiXmlElement*?Broadcast_ver?=?docHandle.FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").ToElement();
????TiXmlNode?*?node?=??Broadcast_ver->FirstChild("BROADCAST_VERSION");
????Broadcast_ver->RemoveChild(node);
也可以刪除整個SOURCE_1節點:
TiXmlHandle?docHandle(?&doc?);
????TiXmlElement*?Broadcast?=?docHandle.FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("Broadcast").ToElement();
????TiXmlNode?*?node?=??Broadcast->FirstChild("SOURCE_1");
????Broadcast->RemoveChild(node);
刪除BROADCAST_VERSION的info屬性:
TiXmlHandle?docHandle(?&doc?);
????TiXmlElement*?Broadcast_ver?=?docHandle.FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChildElement("BROADCAST_VERSION").ToElement();
????Broadcast_ver->RemoveAttribute("info");? // 刪除info
可以借助NextSiblingElement()方法實現遞歸刪除.
三,添加節點,屬性值
例如在SOURCE_3下添加BROADCAST_PID節點:
TiXmlHandle?docHandle(?&doc?);
????TiXmlElement*?Broadcast?=?docHandle.FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("Broadcast").ToElement();
????TiXmlElement*?Broadcast_Pid?=? new?TiXmlElement("BROADCAST_PID");
????TiXmlText?*text?= new?TiXmlText("7215");
????Broadcast_Pid->SetAttribute("info","the?pid");
????Broadcast_Pid->LinkEndChild(text);
????Broadcast->LinkEndChild(Broadcast_Pid);
將在SOURCE_3后添加新的節點:
< BROADCAST_PID? info ="the?pid" >7215 </ BROADCAST_PID >
四,最后說一下中文亂碼的問題
亂碼是由于GB2312與UTF8之間轉換不當造成的,tinyxml在處理UTF8本身沒有問題,當你打開一個UTF8的文檔,可以在加載的時候指定UTF8的方式,或者文檔聲明處指明的編碼格式,tinyxml會按照相應的編碼格式加載,但很多時候當我們輸出或寫入中文字段時會出現亂碼,無論在內存,還是打印出來的內容.這是因為我們的軟件通常是GB2312編碼,而讀取或寫入的內容是UTF8,自然就會出錯.可以借助網上的兩個函數來實現轉換(原作者不詳):
???? void?ConvertUtf8ToGBK(CString&?strUtf8)?
???? {
????????int?len=MultiByteToWideChar(CP_UTF8,?0,?(LPCTSTR)strUtf8,?-1,?NULL,0);
????????unsigned?short?*?wszGBK?=?new?unsigned?short[len+1];
????????memset(wszGBK,?0,?len?*?2?+?2);
????????MultiByteToWideChar(CP_UTF8,?0,?(LPCTSTR)strUtf8,?-1,?wszGBK,?len);
????????len?=?WideCharToMultiByte(CP_ACP,?0,?wszGBK,?-1,?NULL,?0,?NULL,?NULL);
????????char?*szGBK=new?char[len?+?1];
????????memset(szGBK,?0,?len?+?1);
????????WideCharToMultiByte?(CP_ACP,?0,?wszGBK,?-1,?szGBK,?len,?NULL,NULL);
????????strUtf8?=?szGBK;
????????delete[]?szGBK;
????????delete[]?wszGBK;
????}
???? void?ConvertGBKToUtf8(CString&?strGBK)
???? {
????????int?len=MultiByteToWideChar(CP_ACP,?0,?(LPCTSTR)strGBK,?-1,?NULL,0);
????????unsigned?short?*?wszUtf8?=?new?unsigned?short[len+1];
????????memset(wszUtf8,?0,?len?*?2?+?2);
????????MultiByteToWideChar(CP_ACP,?0,?(LPCTSTR)strGBK,?-1,?wszUtf8,?len);
????????len?=?WideCharToMultiByte(CP_UTF8,?0,?wszUtf8,?-1,?NULL,?0,?NULL,?NULL);
????????char?*szUtf8=new?char[len?+?1];
????????memset(szUtf8,?0,?len?+?1);
????????WideCharToMultiByte?(CP_UTF8,?0,?wszUtf8,?-1,?szUtf8,?len,?NULL,NULL);
????????strGBK?=?szUtf8;
????????delete[]?szUtf8;
????????delete[]?wszUtf8;
????}
總結
以上是生活随笔為你收集整理的tinyxml学习一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: freemarker加载模板的三种方法
- 下一篇: 二、crm用户登录实现