国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

C++中處理XML文件

2024-07-21 02:19:10
字體:
來源:轉載
供稿:網友
寫unmanaged code在.net時代成為一種很悲慘的事,當你需要處理xml文件時,這種感覺會變得尤其強烈。fcl中的system.xml多簡單啊,連steve ballmer都知道怎么用。

事情不會總是那么理想的,如果你要在c/c++程序里處理xml怎么辦呢?

選擇一:市面上的xml lib還是有幾個的,最有名的當然是libxml。我一年前用過,很不錯,我還特意寫了一份簡明教程,后來不知擱哪兒了。

選擇二:ms的msxml,我要介紹的就是這個。

先說一下在msdn哪里找文檔吧,往下看的時候也好有個參考:在index里打:windows media services 9 series sdk=>programming reference=>programming reference (c++)=>xml dom interfaces (c++)。什么?windows media?呵呵,不錯,我覺得這個guide反而是最清楚的,你直接找msxml,得到的結果,我覺得還沒這個好。

在c程序里調用msxml基本就是一堆com接口,不過在visual studio里操作先要做點簡單的設置:

在你的project里add references=>com標簽=>microsoft xml v4.0,5.0其實也有了,但因為是和office一起發布的,覺得有點怪,不想用,反正也未必用什么很怪異的功能,4.0可以了。



然后在加入這兩行:

#include <msxml2.h>
#import <msxml4.dll>

頭文件和dll庫。什么?在哪里加?頭文件或者c/cpp文件啊,哪里合適放哪兒。

然后就開始編程了,先定義兩個必用的變量:

ixmldomdocumentptr xmlfile = null;
ixmldomelement* xmlroot = null;

為什么是必用的?  汗...

第一步當然是初始化com:

if(failed(coinitialize(null))) ....

接下來初始化xmlfile對象:

if(failed(xmlfile.createinstance("msxml2.domdocument.4.0"))) ...

然后就可以加載xml文件了:

_variant_t varxml(l"c://test.xml"); //l for unicode
variant_bool varout;
xmlfile->load(varxml, &varout);

取得root element:

xmlfile->get_documentelement(&xmlroot))

取得第一級element:

ixmldomnodelist* xmlchildnodes = null;
xmlroot->get_childnodes(&xmlchildnodes);

遍歷所有第一級element:

ixmldomnode* currentnode = null;
while(!failed(xmlchildnodes->nextnode(&currentnode)) && currentnode != null)
{
//do something
}

取得當前element的名稱:

bstr nodename;
currentnode->get_nodename(&nodename);

取得當前element的一個attribute(假設這個attribute叫type)的值:

ixmldomnamednodemap* attributes = null;
ixmldomnode* attributename = null;
_bstr_t bstrattributename = "type";
bstr nameval;
currentnode->get_attributes(&attributes);
attributes->getnameditem(bstrattributename, &attributename);
attributename->get_text(&nameval);

需要注意的是,你要記住釋放所有的借口,ixmldom***->release(),這可不是.net,有人幫你gc,你得自己調用release()來減reference count,it's com, remember?

好了,大致就這樣,順便提一下xpath:

_bstr_t bstrxmlquery = l"/books/book[@type=scifi and @author=fox]";
ixmldomnodelist* nodes = null;
if(failed(xmlroot->selectnodes(bstrxmlquery, &nodes)) || failed(nodes->get_length(&length)) || length == 0)
//no match found or something went wrong
else
//match found

上面是找這樣的node:

<books>
<book type="scifi" author="fox">....
</book>
....
</books>

具體的xpath語法就查手冊吧,到處都有。

哦,對了,忘了說:如果你全部用atl的類的話,借口的調用會簡單一點,不過很容易轉換的,比如:

ixmldomdocument* 對應 ixmldomdocumentptr(我這里用了),其他基本也是加個ptr,我不廢話了。

最后提供一個sample,我臨時攢的。工作的時候寫的程序當然不能拿來貼的,呵呵。這個sample基本就是遍歷整個xml,然后報告一遍文件的結構,對每個node,如果它有一個叫id的attribute,就同時打印id的值。if you want the complete vs project, shoot me an email. but i guess no one really needs it anyway, right, : )

#include "stdafx.h"
#include <windows.h>
#include <msxml2.h>
#import <msxml4.dll>

handle logfile = null;

#define indent 4

#define testhr(hr) /
{ /
if(failed(hr)) goto fail; /
}

void printchild(ixmldomnodelist* nodelist, int level)
{
if(nodelist == null)
return;

ixmldomnode* currentnode = null;
ixmldomnodelist* childnodes = null;
ixmldomnamednodemap* attributes = null;
ixmldomnode* attributeid = null;

while(!failed(nodelist->nextnode(&currentnode)) && currentnode != null)
{
bstr nodename;
testhr(currentnode->get_nodename(&nodename));
dword dwbyteswritten;
for(int i=0; i<level*indent; i++)
writefile(logfile, l" ", (dword)(sizeof(wchar)), &dwbyteswritten, null);

//wchar msg[max_size];
//wsprintf(msg, l"%s ", nodename);
writefile(logfile, nodename, (dword)(wcslen(nodename)*sizeof(wchar)), &dwbyteswritten, null);

testhr(currentnode->get_attributes(&attributes));
if(attributes!=null)
{
_bstr_t bstrattributename = "id";
bstr idval;
testhr(attributes->getnameditem(bstrattributename, &attributeid));
if(attributeid != null)
{
testhr(attributeid->get_text(&idval));
writefile(logfile, l" ", (dword)(sizeof(wchar)), &dwbyteswritten, null);
writefile(logfile, idval, (dword)(wcslen(idval)*sizeof(wchar)), &dwbyteswritten, null);
writefile(logfile, l"/r/n", (dword)(2*sizeof(wchar)), &dwbyteswritten, null);
attributeid->release(); attributeid = null;
}
else
{
writefile(logfile, l"/r/n", (dword)(2*sizeof(wchar)), &dwbyteswritten, null);
}
attributes->release(); attributes = null;

}
else
{
writefile(logfile, l"/r/n", (dword)(2*sizeof(wchar)), &dwbyteswritten, null);
}

testhr(currentnode->get_childnodes(&childnodes));
printchild(childnodes, level+1);
currentnode=null;
}

fail:
if(childnodes!=null)
childnodes->release();
if(attributeid!=null)
attributeid->release();
if(attributes!=null)
attributes->release();
if(currentnode != null)
currentnode->release();
}

int _tmain(int argc, _tchar* argv[])
{

ixmldomdocumentptr xmlfile = null;
ixmldomelement* xmlroot = null;
_variant_t varxml(l"c://demo1.xml");

logfile = createfile(l"log.txt", generic_write, 0, null, create_always, file_attribute_normal, null);
if(logfile == invalid_handle_value)
goto fail;

testhr(coinitialize(null));

testhr(xmlfile.createinstance("msxml2.domdocument.4.0"));

variant_bool varout;
testhr(xmlfile->load(varxml, &varout));

testhr(xmlfile->get_documentelement(&xmlroot));

bstr rootname;
dword dwbyteswritten;
testhr(xmlroot->get_nodename(&rootname));
writefile(logfile, rootname, (dword)(wcslen(rootname)*sizeof(wchar)), &dwbyteswritten, null);
writefile(logfile, l"/r/n", (dword)(2*sizeof(wchar)), &dwbyteswritten, null);

ixmldomnodelist* xmlchildnodes = null;
testhr(xmlroot->get_childnodes(&xmlchildnodes));

printchild(xmlchildnodes, 2);

fail:
if(logfile != invalid_handle_value)
closehandle(logfile);
if(xmlchildnodes!=null)
xmlchildnodes->release();
if(xmlroot!=null)
xmlroot->release();
return 0;
}





發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 萨迦县| 绿春县| 大同县| 上高县| 集安市| 澄迈县| 安丘市| 沧州市| 赞皇县| 新建县| 乳山市| 西贡区| 锦屏县| 勐海县| 连江县| 富裕县| 陇南市| 丹寨县| 婺源县| 综艺| 濮阳县| 仪征市| 南康市| 六枝特区| 息烽县| 明溪县| 通河县| 阳城县| 肃宁县| 焦作市| 南部县| 潮安县| 外汇| 福海县| 韶关市| 赤水市| 太谷县| 黄骅市| 平远县| 蕉岭县| 武胜县|