亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

史上最最靠譜,又雙叒叒簡(jiǎn)單的基于MSXML的XML解析指南-C++

Ashin / 1436人閱讀

摘要:史上最最靠譜,又雙叒叒簡(jiǎn)單的基于的解析指南最近做相關(guān)的項(xiàng)目,遇到同時(shí)使用和來(lái)解析文件中信息的問(wèn)題,這類(lèi)問(wèn)題如果做開(kāi)發(fā)也會(huì)經(jīng)常用到?;诘募夹g(shù),用于處理操作系統(tǒng)隨附的。提供本機(jī)實(shí)現(xiàn),同時(shí)支持和。包含基于事件的分析器。

史上最最靠譜,又雙叒叒簡(jiǎn)單的基于MSXML的XML解析指南-C++

最近做C++相關(guān)的項(xiàng)目,遇到同時(shí)使用COM和MSXML來(lái)解析XML文件中信息的問(wèn)題,這類(lèi)問(wèn)題如果做MFC開(kāi)發(fā)也會(huì)經(jīng)常用到。
在網(wǎng)上搜了一整圈,確實(shí)很難找到可用的code,總算自己研究出高效而簡(jiǎn)單的方法,借此機(jī)會(huì)總結(jié)一下,并分享給大家。

附 VS Project鏡像:
SimpleParser4MSXML-cpp: C++語(yǔ)言寫(xiě)的MSXML的簡(jiǎn)單使用示例, COM 和 MFC 開(kāi)發(fā)中比較常用。
https://github.com/yanglr/Sim...
點(diǎn)擊”Raw”可看到源碼,歡迎fork或star~



首先簡(jiǎn)要列舉一下MSXML技術(shù)的基本特點(diǎn)。

基于 COM 的技術(shù),用于處理 Windows 操作系統(tǒng)隨附的 XML。
MSXML 提供 DOM 本機(jī)實(shí)現(xiàn),同時(shí)支持 XPath 和 XSLT。
包含 SAX2 基于事件的分析器。
流程設(shè)計(jì)

首先簡(jiǎn)要介紹一下大概流程:

初始化COM

創(chuàng)建一個(gè)IDOMDocument對(duì)象xmlDoc,使用xmlDoc -> load() 或 loadXML()方法讀入 XML源

調(diào)用selectNodes()或者selectSingleNode()函數(shù),選取指定的節(jié)點(diǎn)對(duì)象。

通過(guò)IXMLDOMNode對(duì)象的屬性和方法讀取節(jié)點(diǎn)對(duì)象的內(nèi)容。

通過(guò)IXMLDOMNode對(duì)象的屬性和方法設(shè)置節(jié)點(diǎn)對(duì)象的內(nèi)容。

通過(guò)調(diào)用xmlDoc -> save()保存XML文件。

關(guān)閉COM

需要解決的問(wèn)題:

xml信息有哪幾種讀取形式(xml文件或wchar)

如何選取節(jié)點(diǎn),and取節(jié)點(diǎn)屬性有哪些方法?

IXMLDOMNode 與 IXMLDOMElement 接口有什么聯(lián)系和區(qū)別?

節(jié)點(diǎn)如果是數(shù)組,怎么操作?

如何為屬性插入屬性

字符串的轉(zhuǎn)換

xml信息有哪幾種讀取形式(xml文件或wchar)

xml文件

從文件中導(dǎo)入xml內(nèi)容,使用url或filePath

VARIANT_BOOL bSuccess = false;
HRESULT hr = iXMLDoc->load(CComVariant(L"./test.xml"), &bSuccess); // 此處的L可以省略

當(dāng)已變量方式傳人filePath時(shí),需要使用c_str()函數(shù)轉(zhuǎn)換一下,代碼如下:

VARIANT_BOOL bSuccess = false;
filePath = "./test.xml";
HRESULT hr = iXMLDoc->load(CComVariant(filePath.c_str()), &bSuccess);

已以字符串格式讀入的xml完整代碼

先定義一個(gè)BSTR常量

const wchar_t *src = L""
L"
"
L"
"
L"  Hey
"
L"    
"
L"    
"
L"    
"
L"    
"
L"  
"
L"
";

然后從BSTR導(dǎo)入xml內(nèi)容:

VARIANT_BOOL bSuccess = false;
iXMLDoc->loadXML(CComBSTR(src), &bSuccess);

注: BSTR字符串是用于COM組件對(duì)象模型的字符串格式, 字符串以表示字符串長(zhǎng)度的4字節(jié)整數(shù)開(kāi)始, 然后跟上UTF-16編碼的wchar_t字符串(包括0結(jié)束標(biāo)志)。BSTR類(lèi)型的變量是一個(gè)指針, 指向字符串的第一個(gè)字符處。

如何選取節(jié)點(diǎn),and取節(jié)點(diǎn)屬性有哪些方法?

搜索節(jié)點(diǎn)名字

CComBSTR sstrRoot(L"root"); // sstrRoot("root");
CComPtr rootNode;
HRESULT hr = iXMLDoc->selectSingleNode(sstrRoot, &rootNode);
CComPtr textNode;
hr = rootNode->selectSingleNode(CComBSTR(L"text"), &textNode); // 搜索第一個(gè)"text"節(jié)點(diǎn)
IXMLDOMNode 與 IXMLDOMElement 接口有什么聯(lián)系和區(qū)別

IXMLDOMElement接口繼承于IXMLDOMNode接口,但除了從IXMLDOMNode接口繼承的方法之外,IXMLDOMElement接口還向外暴露以下方法:

方法 說(shuō)明
get_tagName 檢索元素名稱(chēng)(在tag之間的文本)。
getAttribute 檢索所指定名字的屬性的值。
getAttributeNode 檢索所指定名字的屬性的節(jié)點(diǎn)
getElementsByTagName 檢索與提供的名稱(chēng)匹配的所有子元素的列表。
removeAttribute 移動(dòng)或替換給定名稱(chēng)的屬性
removeAttributeNode 從這個(gè)元素中移除指定的屬性
setAttribute 為給定名稱(chēng)的屬性設(shè)置值
setAttributeNode 在此元素上添加或替換提供的屬性節(jié)點(diǎn)。
節(jié)點(diǎn)如果是數(shù)組,怎么操作?

先使用get_childNodes函數(shù)獲得子節(jié)點(diǎn)列表,然后遍歷之用get_item依次取出每一項(xiàng)進(jìn)行處理。

    CComPtr pRootElement;
    CComPtr pNodeList;
    pRootElement->get_childNodes(&pNodeList); // Child node list
    long nLen;
    pNodeList->get_length(&nLen);    // Child node list
    for (long index = 0; i != nLen; ++index) // Traverse
    {
        CComPtr pCurNode;
        hr = pNodeList->get_item(index, &pCurNode);
        do();  // 此處可做任何你想做的事情
    }
如何為屬性插入屬性

使用Element->setAttribute()即可,具體如下:

CComPtr imageElement;
xmlDocData->createElement(CComBSTR(L"Image"), &imageElement); // 創(chuàng)建節(jié)點(diǎn)"Image"
imageElement->setAttribute(CComBSTR(L"Type"), CComVariant(CComBSTR(imageType.c_str())));  // 添加屬性"Type"
字符串的轉(zhuǎn)換與輸出

直接使用printf函數(shù)+“%ls”或wprintf函數(shù)+“%s”打印BSTR類(lèi)字符串

    CComBSTR ssName;
    printf("Node name:%ls
", ssName);   // 用%ls打印BSTR字符串內(nèi)容
    SysFreeString(ssName);               // 用完字符串后必須釋放      

    CComBSTR ssName;
    wprintf(L"Node name:%s
", ssName);   // 這里的L不能省略
    SysFreeString(ssName);

CComBSTR類(lèi)字符串的內(nèi)容復(fù)制到wstring中,然后使用wcout輸出

   CComBSTR ssName;
   wstring bstrText(ssName);
   wcout << bstrText << endl;

先將CComBSTR類(lèi)字符串強(qiáng)轉(zhuǎn)為LPCTSTR類(lèi)型后,然后使用wcout輸出

對(duì)CStringW類(lèi)字符串而言,這已經(jīng)是一種比較簡(jiǎn)單的方式了。

   CComBSTR ssName;
   CString cstring(ssName);
   wcout << (LPCTSTR)cstring << endl;

CComBSTR類(lèi)字符串的內(nèi)容復(fù)制到CW2A類(lèi)字符串(多字節(jié)字符串)中,然后使用wcout輸出

CComBSTR ssName;
CW2A printstr(ssName);
cout << printstr << endl;
主要代碼
#include    // 含有 MSXML最新版
#include 
#include "atlstr.h"  // 含有CString, CStringW和CW2A
#include   // 包含wcout函數(shù)
#include     // 包含 c_str()函數(shù), wcout
#include "comutil.h" // 包含_bstr_t
using namespace std;

const wchar_t *src = L""
L"
"
L"
"
L"  Hey
"
L"    
"
L"    
"
L"    
"
L"    
"
L"  
"
L"
";

int main()
{
    CoInitialize(NULL); // Initialize COM

    CComPtr iXMLDoc;  // Or use CComPtr, CComPtr

    try
    {
        HRESULT hr = iXMLDoc.CoCreateInstance(__uuidof(DOMDocument));
        //     iXMLDoc.CoCreateInstance(__uuidof(DOMDocument60));

        // Load the file. 
        VARIANT_BOOL bSuccess = false;

        // Load it from a url/filename...
        hr = iXMLDoc->load(CComVariant(L"./test.xml"), &bSuccess);
        // filePath = "./test.xml";
        // hr = iXMLDoc->load(CComVariant(filePath.c_str()), &bSuccess);

        // or from a BSTR...
        // iXMLDoc->loadXML(CComBSTR(src), &bSuccess);

        // Get a smart pointer (sp) to the root
        CComPtr pRootElement;
        hr = iXMLDoc->get_documentElement(&pRootElement); // Root elements

        // Get Attribute value of the note "root"
        CComBSTR ssDesc("desc");
        CComVariant deVal(VT_EMPTY);
        hr = pRootElement->getAttribute(ssDesc, &deVal);

        CComBSTR sstrRoot(L"root"); // sstrRoot("root");
        CComPtr rootNode;
        hr = iXMLDoc->selectSingleNode(sstrRoot, &rootNode);  // Search "root"

        CComBSTR rootText;
        hr = rootNode->get_text(&rootText);
        if (SUCCEEDED(hr))
        {
            wstring bstrText(rootText);
            wcout << "Text of root: " << bstrText << endl;
        }

        CComPtr descAttribute;
        hr = rootNode->selectSingleNode(CComBSTR("@desc"), &descAttribute); // Atrribute需要用@, 而各個(gè)節(jié)點(diǎn)不能使用@作為前綴來(lái)搜索
        CComBSTR descVal;
        hr = descAttribute->get_text(&descVal);
        if (SUCCEEDED(hr))
        {
            wstring bstrText(descVal);
            wcout << "Desc Attribute: " << bstrText << endl;
        }

        if (!FAILED(hr))
        {
            wstring strVal;
            if (deVal.vt == VT_BSTR)
                strVal = deVal.bstrVal;

            wcout << "desc: " << strVal << endl;
        }

        CComPtr pNodeList;
        pRootElement->get_childNodes(&pNodeList); // Child node list
        long nLen;
        pNodeList->get_length(&nLen);    // Child node list
        for (long i = 0; i != nLen; ++i) // Traverse
        {
            CComPtr pNode;
            hr = pNodeList->get_item(i, &pNode);

            CComBSTR ssName;
            CComVariant val(VT_EMPTY);
            hr = pNode->get_nodeName(&ssName);
            if (SUCCEEDED(hr))
            {
                wstring bstrText(ssName);
                wcout << "Name of node " << (i + 1) << ": " << bstrText << endl;

                CString cstring(ssName);
                // To display a CStringW correctly, use wcout and cast cstring to (LPCTSTR), an easier way to display wide character strings.
                wcout << (LPCTSTR)cstring << endl;

                // CW2A converts the string in ccombstr to a multi-byte string in printstr, used for display output.
                CW2A printstr(ssName);
                cout << printstr << endl;
            }
        }

        /// Add(Append) node
        CComPtr& xmlDocData(iXMLDoc);
        CComPtr imageElement;
        CComPtr newImageNode;
        string imageType = "jpeg";
        char buffer[MAX_PATH];
        GetCurrentDirectory(MAX_PATH, buffer);  //  Get Current Directory
        string path(buffer); // Copy content of char*, generate a string
        string imagePath = path + "com.jpg";

        xmlDocData->createElement(CComBSTR(L"Image"), &imageElement);
        imageElement->setAttribute(CComBSTR(L"Type"), CComVariant(CComBSTR(imageType.c_str()))); // 為當(dāng)前節(jié)點(diǎn)添加屬性
        imageElement->setAttribute(CComBSTR(L"FileName"), CComVariant(CComBSTR(imagePath.c_str())));
        rootNode->appendChild(imageElement, &newImageNode);

        /// Remove "text" node under "root" node
        CComPtr xmlOldNode;
        CComPtr textNode;
        hr = rootNode->selectSingleNode(CComBSTR(L"text"), &textNode); // Search "text" node        
        hr = rootNode->removeChild(textNode, &xmlOldNode);

        /// Update XML
        hr = iXMLDoc->save(CComVariant("updated.xml"));
    }
    catch (char* pStrErr) {
        // Some error...
        std::cout << pStrErr << std::endl << std::endl;
    } // catch
    catch (...) {
        // Unknown error...
        std::cout << "Unknown error..." << std::endl << std::endl;
    }

    // Release() - that gets done automatically, also can manually do for each opened node or elements.
    // iXMLDoc.Release();

    // Stop COM
    CoUninitialize();

    system("pause");
    return 0;
}

運(yùn)行結(jié)果:

運(yùn)行完,得到的update.xml內(nèi)容為:
https://raw.githubusercontent...


參考資料:

IXMLDOMElement接口

Using the MSXML Parser

MFC C++ XML Parse - Using MSXML

如何:各種字符串類(lèi)型之間轉(zhuǎn)換 | Microsoft Docs

本文原載于本人csdn博客 →
https://blog.csdn.net/lzuacm/...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/110405.html

相關(guān)文章

  • 實(shí)用性前端知識(shí) - 收藏集 - 掘金

    摘要:與面向?qū)ο缶幊塘蠓较蛑阃黄魄岸松钠脚_(tái)期前端掘金無(wú)論我們從事何種職業(yè),在職業(yè)生涯的某個(gè)階段,都或多或少會(huì)遇到所謂的平臺(tái)期。目前為止,已經(jīng)有個(gè)用戶(hù)通過(guò)認(rèn)證登觀點(diǎn)年前端初學(xué)者的生存指南前端掘金逝者如斯夫,不舍晝夜。 你可能聽(tīng)說(shuō)過(guò)函數(shù)式編程(Functional programming),甚至已經(jīng)使用了一段時(shí)間。 但是,你能說(shuō)清楚,它到底是什么嗎? 網(wǎng)上搜索一下,你會(huì)輕松找到好多答案...

    Honwhy 評(píng)論0 收藏0
  • 雙叒叕是一個(gè)動(dòng)態(tài)簡(jiǎn)歷

    摘要:標(biāo)點(diǎn)處理根據(jù)傳入的字符來(lái)判斷下一個(gè)字符出現(xiàn)的延遲時(shí)間,即方法的第二個(gè)參數(shù)。年初的時(shí)候試著重寫(xiě)了這個(gè)項(xiàng)目,感覺(jué)已是沒(méi)有什么難度了,不過(guò)也是面向過(guò)程,一頓操作罷了。 先看效果 請(qǐng)戳這里看預(yù)覽這里是代碼 見(jiàn)過(guò)了?別走,這是與眾不同的地方 針對(duì)移動(dòng)端優(yōu)化了體驗(yàn) 支持動(dòng)畫(huà)跳過(guò) 支持多段動(dòng)畫(huà) 標(biāo)點(diǎn)字符特殊處理,停留時(shí)間略長(zhǎng)于字符時(shí)間 typescript 編寫(xiě) 對(duì)功能進(jìn)行了封裝處理,可以直接引入...

    firim 評(píng)論0 收藏0
  • 雙叒叕是一個(gè)動(dòng)態(tài)簡(jiǎn)歷

    摘要:標(biāo)點(diǎn)處理根據(jù)傳入的字符來(lái)判斷下一個(gè)字符出現(xiàn)的延遲時(shí)間,即方法的第二個(gè)參數(shù)。年初的時(shí)候試著重寫(xiě)了這個(gè)項(xiàng)目,感覺(jué)已是沒(méi)有什么難度了,不過(guò)也是面向過(guò)程,一頓操作罷了。 先看效果 請(qǐng)戳這里看預(yù)覽這里是代碼 見(jiàn)過(guò)了?別走,這是與眾不同的地方 針對(duì)移動(dòng)端優(yōu)化了體驗(yàn) 支持動(dòng)畫(huà)跳過(guò) 支持多段動(dòng)畫(huà) 標(biāo)點(diǎn)字符特殊處理,停留時(shí)間略長(zhǎng)于字符時(shí)間 typescript 編寫(xiě) 對(duì)功能進(jìn)行了封裝處理,可以直接引入...

    iKcamp 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<