在BinPlayer build 14 中应该就可以看到. 简单构架XML, UTF-8编码, 精简命名.
剩下一个问题就是解析它了,曾经有3个方案摆在我面前,我选择了第三者.
1. 自己编写代码解析UTF-8和XML.
2. 使用第三方组件.
3. 使用Windows自身组件MSXML.
如果翻翻CSDN,大多数结论都是前两个,不知道是为什么.不排除大多数人是使用"不择手段"的思想.
MSXML是Windows核心组件之一.不过不是唯一的XML解析组件.后来还有xmlite,不过xmlite从Vista开始才被Windows自带.
MSXML里面的东西也很多.常用的是DOM和SAX2.这里使用的是DOM.(注意,他们都是COM组件).
整体流程大致:
1. 初始化组件.
2. Load XML. (IXMLDOMDocument::load);
3. 查询Node.
关键函数:
IXMLDOMNode::selectSingleNode
IXMLDOMNode::selectNodes
这里要使用一个查询语句查询,就是XPath表达式(XPath expression),你可以把它理解为SQL.
整体过程很简单,下面是我开始测试bpls时候使用的测试代码.
doActionsWithNode函数用来显示节点的"t"属性.(说到这里,如果搞不清什么叫节点和属性,最好先去看看资料.MSDN里面也有,写得也很全)
pXMLDom->selectSingleNode(TEXT("//BPF[2][@t|@a|@s|@b|@e]"), &pNode);
这句的意思就是查询拥有t,a,s,b,e属性的第二个BPF节点.
pXMLDom->selectNodes(TEXT("//BPF[@t|@a|@s|@b|@e]"), &pNodes);
这句意思是查询所以的拥有t,a,s,b,e属性的BPF节点.
这个代码简单改改就可以适合很多应用.
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <objbase.h>
#include <msxml2.h>
BOOL doActionsWithNode (IXMLDOMNode *pNode) {
if (NULL == pNode) return FALSE;
BSTR bstr = NULL;
IXMLDOMNamedNodeMap * pNodeMap;
IXMLDOMNode * pNodeTemp;
pNode->get_attributes(&pNodeMap);
if (NULL == pNodeMap) return FALSE;
// read attributes
pNodeMap->getNamedItem(TEXT("t"), &pNodeTemp);
if (NULL != pNodeTemp) {
pNodeTemp->get_text(&bstr);
wprintf(TEXT("t %s\n"), bstr);
SysFreeString(bstr);
pNodeTemp->Release();
}
// freeMap
pNodeMap->Release();
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
IXMLDOMDocument *pXMLDom=NULL;
IXMLDOMNodeList *pNodes=NULL;
IXMLDOMNode *pNode=NULL;
BSTR bstr = NULL;
VARIANT_BOOL status;
VARIANT var;
long length;
HRESULT hr;
//Initialize COM
CoInitialize(NULL);
//Initialize DOM
hr = CoCreateInstance(__uuidof(DOMDocument30),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&pXMLDom);
if (FAILED(hr)) return 0;
pXMLDom->put_async(VARIANT_FALSE);
pXMLDom->put_validateOnParse(VARIANT_FALSE);
pXMLDom->put_resolveExternals(VARIANT_FALSE);
//prepare a string to load XML
VariantInit(&var);
V_BSTR(&var) = SysAllocString(TEXT("C:\\bpls.bpls"));
V_VT(&var) = VT_BSTR;
//Load XML
pXMLDom->load(var, &status);
SysFreeString(V_BSTR(&var));
if (status!=VARIANT_TRUE) {
return 0;
}
// Query a single node.
pXMLDom->selectSingleNode(TEXT("//BPF[2][@t|@a|@s|@b|@e]"), &pNode);
if (NULL != pNode) {
doActionsWithNode(pNode);
pNode->Release();
}
// Query a node-set.
pXMLDom->selectNodes(TEXT("//BPF[@t|@a|@s|@b|@e]"), &pNodes);
if (NULL != pNodes) {
pNodes->get_length(&length);
for (long i=0; i
pNodes->get_item(i, &pNode);
if (NULL != pNode) {
doActionsWithNode(pNode);
pNode->Release();
}
}
pNodes->Release();
}
//Release
pXMLDom->Release();
CoUninitialize();
return 0;
}
cplusplus小程序
ReplyDelete在c ++中创建文件比较实用程序