• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            笑看風云淡

            寵辱不驚,看庭前花開花落;去留無意,望天空云卷云舒
            posts - 96, comments - 48, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理

            使用MSXML在VC++中解析XML文件

            Posted on 2009-08-25 15:29 天之驕子 閱讀(5131) 評論(0)  編輯 收藏 引用

            好久沒有在VC++里面解析XML了,昨天遇到一個問題,從昨天下午一直到今天上午,差不多搞了一天,才終于把問題解決了。
            使用MSXML在VC++中解析XML文件時候,只需要做到下面幾點:
            1、初始化COM庫,CoInitialize(NULL);可以放在InitInstance()函數里面。釋放COM庫,CoUninitialize();可以放在ExitInstance()函數里面。
            2、在頭文件里面加入如下代碼

            #import "MSXML6.dll" rename_namespace("MSXML6") named_guids
            using namespace MSXML6;
            因為解析的時候要用到CComVariant類,所以還要加上
            #include <atlbase.h>
            3、解析XML文件。
            需要解析的XML文件如下:
            <?xml version="1.0" encoding="UTF-8"?>
            <SCL xmlns="http://www.iec.ch/61850/2003/SCL">
                
            <Address type="MAC-Address" xsi:type="tP_MAC-Address">
                01-0C-CD-01-00-08
            </Address>
            </SCL>
            首先要加載XML文件,代碼如下:
                HRESULT hr;
                IXMLDOMDocument 
            *pDoc=NULL;

                CString strFileName;
                
                CFileDialog fileDlg(TRUE);
                fileDlg.m_ofn.lpstrTitle
            ="打開XML文件";
                fileDlg.m_ofn.lpstrFilter
            ="XML Files(*.xml)\0*.xml\0All Files(*.*)\0*.*\0\0";
                fileDlg.m_ofn.lpstrDefExt
            ="xml";
                
            if(fileDlg.DoModal() != IDOK)
                    
            return;
                strFileName
            =fileDlg.GetPathName();        //獲得要解析的XML文件的路徑名
                ASSERT(!strFileName.IsEmpty());

                
            if(SUCCEEDED(CoCreateInstance(CLSID_DOMDocument,NULL,
                    CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument,(
            void**)&pDoc)))    //創建Document對象
                {
                    CComVariant vPath(strFileName);
                    VARIANT_BOOL isSuccessful;
                    pDoc
            ->raw_load(vPath,&isSuccessful);    //加載要解析的XML文件
                    if(isSuccessful!=VARIANT_TRUE)
                    
            {
                        AfxMessageBox(
            "wrong!");
                        
            return;
                    }

                }
            我當時在加載XML文件的時候老是報錯,本來以為是代碼的問題,找了半天都沒問題呀。后來發現XML文件的問題,問題出在xsi:type上,如果將xsi:type改成別的(比如ype就可以了);或者是在根元素里面定義好xsi的意義,修改后的XML文件如下
            <?xml version="1.0" encoding="UTF-8"?>
            <SCL xmlns="http://www.iec.ch/61850/2003/SCL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                
            <Address type="MAC-Address" xsi:type="tP_MAC-Address">
                01-0C-CD-01-00-08
            </Address>
            </SCL>
            現在加載XML文件已經沒有問題了,下面就是解析XML文件了。我所做的工作是得到元素Address的兩個屬性的名稱type和xsi:type,以及它們的屬性值。
            我原來的解析代碼是:
                IXMLDOMElement *pRootElement=NULL;
                IXMLDOMNode 
            *pRootNode=NULL;

                IXMLDOMNamedNodeMap 
            *pAttrMap=NULL;
                IXMLDOMNode 
            *pAttrNode=NULL;
                IXMLDOMNode 
            *pAddrNode=NULL;

                CString strName,strText;
                BSTR bsName,bsText;

                hr
            =pDoc->get_documentElement(&pRootElement);
                
            if(SUCCEEDED(hr) && (pRootElement!=NULL))
                
            {
                    hr
            =pRootElement->QueryInterface(IID_IXMLDOMNode,(void**)&pRootNode);
                    
            if(SUCCEEDED(hr))
                    
            {

                        hr
            =pRootNode->get_firstChild(&pAddrNode);
                        
            if(SUCCEEDED(hr) && (pAddrNode!=NULL))
                        
            {
                            pAddrNode
            ->get_attributes(&pAttrMap);
                            
                            
            long length=0;
                            pAttrMap
            ->get_length(&length);
                            
            for(int i=0;i<length;i++)
                            
            {
                                hr
            =pAttrMap->get_item(i,&pAttrNode);
                                
            if(SUCCEEDED(hr) && (pAttrNode!=NULL))
                                
            {
                                    pAttrNode
            ->get_baseName(&bsName);
                                    pAttrNode
            ->get_text(&bsText);
                                    strName
            =bsName;
                                    strText
            =bsText;
                                    
                                    SysFreeString(bsName);
                                    SysFreeString(bsText);
                                }

                            }

                        }

                    }

                }
            后來調試的時候發現,對xsi:type屬性節點調用get_basename()方法,得到的是type,而不是xsi:type;當然對type屬性節點調用get_basename()方法,得到的是type,這個正常。后來我改用IXMLDOMNode的get_nodeName()方法,才把問題解決了。對xsi:type屬性節點調用get_nodename()方法,得到的是xsi:type;對type屬性節點調用get_nodename()方法,得到的是type。
            修改后的VC++代碼如下
                IXMLDOMElement *pRootElement=NULL;
                IXMLDOMNode 
            *pRootNode=NULL;

                IXMLDOMNamedNodeMap 
            *pAttrMap=NULL;
                IXMLDOMNode 
            *pAttrNode=NULL;
                IXMLDOMNode 
            *pAddrNode=NULL;

                CString strName,strText;
                BSTR bsName,bsText;

                hr
            =pDoc->get_documentElement(&pRootElement);
                
            if(SUCCEEDED(hr) && (pRootElement!=NULL))
                
            {
                    hr
            =pRootElement->QueryInterface(IID_IXMLDOMNode,(void**)&pRootNode);
                    
            if(SUCCEEDED(hr))
                    
            {

                        hr
            =pRootNode->get_firstChild(&pAddrNode);
                        
            if(SUCCEEDED(hr) && (pAddrNode!=NULL))
                        
            {
                            pAddrNode
            ->get_attributes(&pAttrMap);
                            
                            
            long length=0;
                            pAttrMap
            ->get_length(&length);
                            
            for(int i=0;i<length;i++)
                            
            {
                                hr
            =pAttrMap->get_item(i,&pAttrNode);
                                
            if(SUCCEEDED(hr) && (pAttrNode!=NULL))
                                
            {
                                    pAttrNode
            ->get_nodeName(&bsName);
                                    pAttrNode
            ->get_text(&bsText);
                                    strName
            =bsName;
                                    strText
            =bsText;
                                    
                                    SysFreeString(bsName);
                                    SysFreeString(bsText);
                                }

                            }

                        }

                    }

                }
            国产成人无码精品久久久性色| 婷婷久久精品国产| 久久国产午夜精品一区二区三区| 久久精品国产亚洲AV不卡| www.久久精品| 久久福利资源国产精品999| 精品久久久久久国产91| 久久精品国产亚洲av水果派| 思思久久精品在热线热| 精品久久久久久久| 久久国产精品-久久精品| 久久综合给久久狠狠97色| 久久99精品国产麻豆婷婷| 一本一本久久A久久综合精品| 色8久久人人97超碰香蕉987| 久久99国产精品久久99小说| 久久精品国产99国产精品| 久久毛片一区二区| 久久精品亚洲欧美日韩久久| 国产精品成人99久久久久| 久久精品视频免费| 欧美一级久久久久久久大| 久久人人爽人人爽人人AV| 久久精品国产亚洲精品2020| 国产99久久久国产精免费| 亚洲国产精品综合久久网络| 久久综合成人网| 91亚洲国产成人久久精品网址| 综合人妻久久一区二区精品| 热久久最新网站获取| 久久天天躁狠狠躁夜夜avapp| 狠色狠色狠狠色综合久久| 久久久亚洲精品蜜桃臀| 99久久99这里只有免费费精品| 久久精品国产亚洲5555| 国产成人无码久久久精品一| 久久久久久久精品成人热色戒| 国产综合精品久久亚洲| 亚洲国产精品一区二区三区久久 | 国产精品无码久久四虎| 东方aⅴ免费观看久久av|