最近工作上的需要,需要使用C++来与xml进行交互,在学习的过程中遇到了一些问题,从网上也搜索了一些资料,在这里总结一下,既是对初学的梳理,也能方便大家需要接触的人。

  1. 对xml的认识。

xml是一种相对规范严整的解释语言。具体的语法大家可以去查,对我们使用的角度来说,我们只需要了解,他有很多节点(元素)组成,从父元素到其子元素,子元素可以为空,资源拥有属性,可以方便存储数据。以下是一个xml的示例文档:

 <?xml version ="1.0" encoding="UTF-8"?>
    <Picture>
    <Circle>
    <circle name="circle1" radius="12.5"/>
        <circle name="circle2" radius="56.5"/>
    </Circle>
    <Rectangle>
        <rectangle name ="rectangle1" rec_long="20.5" rec_weight="15"/>
        <rectangle name ="rectangle1" rec_long="40" rec_weight="25"/>
        <rectangle name ="rectangle1" rec_long="60" rec_weight="45"/>
    </Rectangle>
</Picture>

2.本实例使用的准备工作

我们使用的平台是VS2005,使用msxml4,使用前准备工作如下:

  1. 下载安装msxml4;

  2. 利用VS2005新建一个项目,我这里使用的是对话框的项目。这里面使用了一个树的控件(TreeControl)

  3. 在项目的stdafx.h头文件最后添上语句:

    #import "msxml4.dll"
    using namespace MSXML2;

    我在这里的时候遇到一个问题:在使用接口时总是报出“error:XX函数:不能确定的符号”,这就让我很迷惑,即使我新插入的msxml4.dll可能有冲突,怎么还会报错呢?况且我还使用了using namespace MSXML2的语句。问题的解决办法是在接下来的接口使用时全部加上MSXML2::作用域。关于问题的原因,是有关于using namespace的使用,我们vs2005创建项目有加上msxml2.h的头文件,由此发生的冲突。

3. 对于操作接口相关说明和理解。(这段文字来自网络)

可以参考一篇博文,http://blog.csdn.net/perddy/article/details/1756481,里面有对接口整个的解释,这里我们可以点一个点:在DOM 接口规范中,有四个基本的接口:Document,Node,NodeList以及NamedNodeMap。在这四个基本接口中,Document接口是对文档进行操作的入口,它是从Node接口继承过来的。Node接口是其他大多数接口的父类,象Documet,Element,Attribute, Text,Comment等接口都是从Node接口继承过来的。NodeList接口是一个节点的集合,它包含了某个节点中的所有子节点。 NamedNodeMap接口也是一个节点的集合,通过该接口,可以建立节点名和节点之间的一一映射关系,从而利用节点名可以直接访问特定的节点。

4. 我们代码的目的,操作上面的xml文档,获取相关的一些属性。

CoInitialize(NULL);//初始化COM资源
 //IXMLDocumentPtr xmlFile=NULL;
CComPtr<MSXML2::IXMLDOMDocument> spXmldoc;
 //初始化xmlFile对象
HRESULT hr=spXmldoc.CoCreateInstance(__uuidof(MSXML2::DOMDocument40));
CComVariant varXml(_T("D:\\testADOproj\\picturedata.xml"));
 //spXmldoc->put_async(VARIANT_FALSE);//设置为同步
if(FAILED(hr))
{
    CString errormess="创建xmlinsatance失败!";
    AfxMessageBox(errormess);
}
else 
{
     try
     {
          spXmldoc->load(varXml);//加载xml
      }
      catch(_com_error e)
      {
           AfxMessageBox(e.ErrorMessage());
           CString errorSee="连接xml出错。";
           AfxMessageBox(errorSee);
      }
 }
 
MSXML2::IXMLDOMElementPtr ChildNode;
CString senoname=_T("//Circle");
ChildNode=(MSXML2::IXMLDOMElementPtr)(spXmldoc->selectSingleNode((_bstr_t)senoname));
long nCount,iCount;

MSXML2::IXMLDOMNodeList * xmlchildnodes=NULL;
ChildNode->get_childNodes(&xmlchildnodes);//获取子元素并且加入到列表
xmlchildnodes->get_length(&iCount); //获得它的子节点的个数,Circlex下面有两个空元素 ,只是属性值不同
//targetNode = selectSingleNode("//NodeName[@NodeAtt='NodeAttValue']")
//如果子元素不为空
if (iCount>0)
{
    MSXML2::IXMLDOMNode *currentNode =NULL;
    MSXML2::IXMLDOMNodePtr preturnNode =NULL;
    for(int i=0;i<iCount;i++)
    {
       xmlchildnodes->get_item(i,&currentNode);
       preturnNode=currentNode->Getattributes()->getNamedItem(_T("radius"));
       _bstr_t temp_radius;
       temp_radius=preturnNode->Gettext();
       addtoItem(temp_radius);
     }
}
//记得要相关释放指针,自己添加
CoUninitialize();//释放COM资源

5. 关于msxml的要注意智能指针的使用。

另外问个问题: IXMLDOMNode *定义指针和IXMLDOMNodePtr 定义有什么不同呢?

暂时写这些,以后在详解。