• <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);
                                }

                            }

                        }

                    }

                }
            狠狠色丁香久久婷婷综合| 久久国产精品99精品国产987| 久久精品国产亚洲欧美| 国内精品久久久久| 久久久亚洲精品蜜桃臀| 国产69精品久久久久APP下载| 久久精品国产网红主播| 久久国产免费直播| 伊人久久大香线焦AV综合影院| 婷婷综合久久中文字幕| 久久99热这里只有精品66| 69久久夜色精品国产69| 欧美午夜A∨大片久久| 久久精品九九亚洲精品| 久久综合色区| 国内精品伊人久久久久| 婷婷五月深深久久精品| 日韩影院久久| 99热热久久这里只有精品68| 无码日韩人妻精品久久蜜桃 | 久久精品一区二区三区不卡| 亚洲国产高清精品线久久| 久久久久久久综合日本亚洲| 亚洲欧美成人综合久久久| 99久久精品免费国产大片| 国产婷婷成人久久Av免费高清 | 亚洲国产天堂久久久久久| 久久九九亚洲精品| 97精品久久天干天天天按摩 | 99久久国产免费福利| 97久久超碰成人精品网站| 久久久久人妻一区精品性色av| 亚洲欧美国产日韩综合久久| 国内精品久久久久久久久| 国产精品久久成人影院| 国产人久久人人人人爽| 久久精品亚洲中文字幕无码麻豆| 日韩久久久久久中文人妻| 午夜不卡久久精品无码免费| 日韩久久久久久中文人妻| 久久久久亚洲AV无码永不|