MSXML2能够很好地处理xml文件,不过也有些需要注意的点
1. MSXML2的加载和释放
loadIndexXml(TCHAR * indexdir) {
if (NULL == indexdir){
return NULL;
}
::CoInitialize(NULL);
MSXML2::IXMLDOMDocumentPtr doc;
doc.CreateInstance(__uuidof(DOMDocument60));
if (VARIANT_FALSE == doc->load(indexdir)){
doc.Release();
return NULL;
}
......do smthing();
doc.Release();
CoUninitialize();
2. 新建一个xml文件
CString setnameindex;
setnameindex.Format("./xxx/%s.xml", name);
//判断文件是否存在
HANDLE hOpenFile = (HANDLE)CreateFile(setnameindex, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hOpenFile == INVALID_HANDLE_VALUE) {
::CoInitialize(NULL);
MSXML2::IXMLDOMDocumentPtr setnamedoc;
setnamedoc.CreateInstance(__uuidof(DOMDocument60));
char* dbfile = (LPSTR)(LPCSTR)setnameindex;
setnamedoc->preserveWhiteSpace = VARIANT_TRUE;//这个必须设置,不然不生效
MSXML2::IXMLDOMProcessingInstructionPtr pProInstruction = NULL;
pProInstruction = setnamedoc->createProcessingInstruction((_bstr_t)(char*)"xml", (_bstr_t)(char*)"version=\"1.0\" encoding=\"utf-8\"");
((MSXML2::IXMLDOMNodePtr)setnamedoc)->appendChild(pProInstruction);
MSXML2::IXMLDOMElementPtr pRootElement = NULL;
pRootElement = setnamedoc->createElement((_bstr_t)(char*)"db");
setnamedoc->PutRefdocumentElement(pRootElement);
((MSXML2::IXMLDOMNodePtr)setnamedoc->documentElement)->appendChild(setnamedoc->createTextNode("\n\t"));
MSXML2::IXMLDOMCommentPtr pComment = setnamedoc->createComment((_bstr_t)(char*)"db");
((MSXML2::IXMLDOMNodePtr)pRootElement)->appendChild(pComment); // 注释
setnamedoc->save((LPSTR)(LPCSTR)setnameindex);
setnamedoc.Release();
//CoUninitialize();
}
3.获取某个节点列表,判断节点是否存在,并做处理
MSXML2::IXMLDOMNodeListPtr node_person_list = ((MSXML2::IXMLDOMNodePtr)doc)->selectNodes("register/person");
if (NULL == node_person_list || node_person_list->Getlength() == 0) {
........不存在的情况
}
else{
........存在的情况
}
xml文件:
<register>
<person name="xxxx" file="./a/b/c.png" date="0"/>
<person name="xxxx" file="./a/b/c.png" date="0"/>
....
</register>
4. 获取节点属性 如name file data
MSXML2::IXMLDOMNodeListPtr node_person_list = ((MSXML2::IXMLDOMNodePtr)doc)->selectNodes("register/person");
for (int i = 0; i < node_person_list->Getlength(); i++)
{
MSXML2::IXMLDOMNodePtr node_item = node_person_list->Getitem(i);
_variant_t var_name = ((MSXML2::IXMLDOMElementPtr)node_item)->getAttribute("name");
_variant_t var_file = ((MSXML2::IXMLDOMElementPtr)node_item)->getAttribute("file");
_variant_t var_date = ((MSXML2::IXMLDOMElementPtr)node_item)->getAttribute("date");
_variant_t var_score = NULL;
var_score = ((MSXML2::IXMLDOMElementPtr)node_item)->getAttribute("score");
n->name = _tcsdup(CString(var_name.bstrVal));
//n->score = wcstol(var_score.bstrVal, NULL, 0);
TCHAR temp[1024];
//_tcscpy(temp, TEXT("facescore/woman/"));
_tcscpy(temp, TEXT(""));
_tcscat(temp, CString(var_file.bstrVal));
n->file = _tcsdup(temp);
//n->feature = (float *)malloc(sizeof(float) * 2048);
n->date = _ttoi((LPCTSTR)(_bstr_t)var_date);
if (var_score.vt != VT_NULL) {
n->score = _ttoi((LPCTSTR)(_bstr_t)var_score);
}
else {
n->score = -1;
}
}
lw->AddTail(n);
}
其中 var_score取出来后,不知道判断是不是取到了正确的值,不能直接使用,错误使用会导致崩溃,判断的方法如下:
if (var_score.vt != VT_NULL) {
n->score = _ttoi((LPCTSTR)(_bstr_t)var_score);
}
5.删除某个节点,并保存
CString dbxml;
dbxml.Format("./xxx/%s.xml", name);
::CoInitialize(NULL);
MSXML2::IXMLDOMDocumentPtr doc;
doc.CreateInstance(__uuidof(DOMDocument60));
if (VARIANT_FALSE == doc->load(((LPSTR)(LPCSTR)dbxml))) {
doc.Release();
return 2;
}
time_t t = time(nullptr);
MSXML2::IXMLDOMNodePtr item;
CString str;
str.Format("db/item[@name=‘%s‘]", name);
//_variant_t var(str);
item = ((MSXML2::IXMLDOMNodePtr)doc)->selectSingleNode(_bstr_t(str));
if (item != NULL) {
item->GetparentNode()->removeChild(item);
}
doc->save((LPSTR)(LPCSTR)dbxml);
doc.Release();
CoUninitialize();
6.更新xml里面某些节点的数据(先删除,再添加)
str.Format("db/item[@name=‘%s‘]/features/feature", duq.name);
//_variant_t var(str);
feature = ((MSXML2::IXMLDOMNodePtr)doc)->selectSingleNode(_bstr_t(str));
if (feature != NULL) {
((MSXML2::IXMLDOMElementPtr)feature)->setAttribute("date", t);
MSXML2::IXMLDOMNodeList *pNodeList = NULL;
feature->get_childNodes(&pNodeList);
Debug_TraceA("UpdataSingleItemToDbXML get_childNodes \n");
if (pNodeList != NULL) {
for (int i = 0; i < pNodeList->Getlength(); i++) {
MSXML2::IXMLDOMNodePtr pNode;
pNodeList->get_item(i, &pNode);
feature->removeChild(pNode);
}
}
for (int i = 0; i < feature_size; i++) {
MSXML2::IXMLDOMNodePtr node_float = doc->createElement("f");
CString s;
s.Format("%.8f", userfeature[i]);
_variant_t var(s);
node_float->put_text(_bstr_t(s));
//node_float->nodeValue.fltVal = p->feature[i];// CComVariant(p->feature[i]);
feature->appendChild(node_float);
}
}
doc->save(dbxml);
doc.Release();
CoUninitialize();
vc中使用MSXML2的注意点
原文:http://www.cnblogs.com/baldermurphy/p/6233687.html