MSXML。获取 Base64 格式的数据

发布于 2024-10-07 19:24:40 字数 589 浏览 0 评论 0原文

我将 C++ 与 MSXML 结合使用,并希望从 XML 文件中获取 Base64 数据。我正在使用这段代码:

    hr = nodeList->get_item((long)i, (IXMLDOMNode **)&vXMLNode);
    if ( FAILED(hr) )
        throw "Unable to retrieve child node";

    vXMLNode->put_dataType(_bstr_t("bin.base64"));

    hr = vXMLNode->get_nodeTypedValue(&varValue);
    if ( FAILED(hr) )
        throw "Unable to retrieve 'xmltext' text";

所以 vXMLNode 是一个带有数据的子节点。 vXMLNode 的节点类型为 NODE_ELEMENT。如果我检查此节点的数据类型,我会得到VT_NULL。因此我将数据作为字符串获取。

我的代码有什么问题?

I'm using C++ with MSXML and want to get data from XML file as Base64. I'm using this code:

    hr = nodeList->get_item((long)i, (IXMLDOMNode **)&vXMLNode);
    if ( FAILED(hr) )
        throw "Unable to retrieve child node";

    vXMLNode->put_dataType(_bstr_t("bin.base64"));

    hr = vXMLNode->get_nodeTypedValue(&varValue);
    if ( FAILED(hr) )
        throw "Unable to retrieve 'xmltext' text";

So vXMLNode is a child node with data. Node type of vXMLNode is NODE_ELEMENT. If I check data type for this node, I get VT_NULL. Therefore I get my data as a string.

What is wrong in my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风向决定发型 2024-10-14 19:24:40

我相信问题出在您提供的示例代码之外。这是一个使用nodeTypedValue 的工作控制台程序。我希望这有帮助。

// Base64CPP.cpp : Defines the entry point for the console application.

//  NOTE:
//  This code is provided as is in the form of a sample with no warranties of any kind, 
//  either expressed or implied for any purpose. Use at your own risk.

#include "stdafx.h"

#include <TCHAR.H>
#include <stdio.h>
#include <sys/stat.h>
#include <fstream>
#include <string.h>

#include <atlbase.h>
#import <msxml4.dll> named_guids
using namespace MSXML2;

inline void EVAL_HR( HRESULT _hr ) 
   { if FAILED(_hr) throw(_hr); }

//  Binary to Base64 Encoding
bool DoEncoding(LPCTSTR lpszXMLFile, LPCTSTR lpszBinFile)
{
    bool bRetVal = false;
    try
    {
        long lFileSize;
        struct stat fileSizeVal;

        //  Get the file size
        if (stat(lpszBinFile, &fileSizeVal) == 0)
        {
            lFileSize = fileSizeVal.st_size;
            if(lFileSize <= 0)
                return false;
        }
        else 
            return false;

        //  Instantiate XML DOMDocument
        CComPtr<IXMLDOMDocument2> spXMLDoc;
        CComPtr<MSXML2::IXMLDOMElement> spDataElement;
        HRESULT hr = spXMLDoc.CoCreateInstance(CLSID_DOMDocument40);
        EVAL_HR(hr);
        spXMLDoc->loadXML(_T("<?xml version='1.0' encoding='UTF-8'?> <Data/>"));

        //  Prepare the top node to store binary data as base64
        spDataElement = spXMLDoc->documentElement;
        ATLASSERT(spDataElement != NULL && _T("Failed to get document element."));

        hr = spDataElement->put_dataType(CComBSTR(_T("bin.base64")));
        EVAL_HR(hr);

        //  Read the file into memory
        std::ifstream binDataFile;
        binDataFile.open(lpszBinFile, std::ios::binary);
        binDataFile.seekg(std::ios::beg);
        SAFEARRAY* psa = SafeArrayCreateVector( VT_UI1, 0L, lFileSize);
        binDataFile.read((char*)psa->pvData, lFileSize);
        binDataFile.close();

        //  Save the binary data into Data node
        VARIANT var;
        VariantInit(&var);
        var.parray = psa;
        var.vt = (VT_ARRAY | VT_UI1 );
        spDataElement->nodeTypedValue = var;

        //  Save the XML Document
        spXMLDoc->save(lpszXMLFile);

        bRetVal = true;
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    return bRetVal;
}

//  Base64 to binary decoding
bool DoDecoding(LPCTSTR lpszXMLFile, LPCTSTR lpszBinFile)
{
    bool bRetVal = false;
    try
    {
        //  Instantiate DOMDocument and load XML file
        CComPtr<IXMLDOMDocument2> spXMLDoc;
        CComPtr<MSXML2::IXMLDOMElement> spDataElement;
        HRESULT hr = spXMLDoc.CoCreateInstance(CLSID_DOMDocument40);
        EVAL_HR(hr);
        CComVariant vtFileName = CComBSTR(lpszXMLFile);
        spXMLDoc->load(vtFileName);

        //  ASSUMPTION: documentElement (top element) contains base64 data
        spDataElement = spXMLDoc->documentElement;
        ATLASSERT(spDataElement != NULL && _T("Failed to get document element."));

        //  Prepare the file for writing
        std::ofstream binDataFile (lpszBinFile, std::ios::out | std::ios::binary);

        //  Save the binary data into data file
        long lDataLength=0;
        hr = SafeArrayGetUBound(spDataElement->nodeTypedValue.parray, 1, &lDataLength);
        EVAL_HR(hr);
        lDataLength++;

        binDataFile.write((char*)(spDataElement->nodeTypedValue.parray->pvData), lDataLength);
        binDataFile.close();

        bRetVal = true;
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    return bRetVal;
}

int main(int argc, char* argv[])
{
    if(argc < 4)
    {//insufficient parameters
        printf(_T("\nSample app to encode/decode binary data as base64 XML using MSXML.\n"));
        printf(_T("\nUsage:\tBase64CPP.exe <e>|<d> <XMLFileName> <BinaryDataFile>"));
        printf(_T("\n\nExamples:"));
        printf(_T("\n\tEncode binary data in 1.jpg and save as Base64 into 1.xml:"));
        printf(_T("\n\t\tBase64CPP.exe e c:\\1.xml c:\\1.jpg\n"));
        printf(_T("\n\tDecode base64 data in 1.xml and save as binary into 2.jpg:"));
        printf(_T("\n\t\tBase64CPP.exe d c:\\1.xml c:\\2.jpg\n\n"));
        return -1;
    }

    try
    {
        HRESULT hr = CoInitialize(NULL);
        EVAL_HR(hr);

        if(_tcsicmp(argv[1], _T("e")) == 0)
        {
            if(DoEncoding(argv[2], argv[3]))
                printf(_T("Success. See %s for results."), argv[2]);
            else
                printf(_T("Failed."));
        }
        else
        {
            if(DoDecoding(argv[2], argv[3]))
                printf(_T("Success. See %s for results."), argv[3]);
            else
                printf(_T("Failed."));
        }
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    CoUninitialize();
    getchar();
    return 0;
}

I believe the problem lies outside of your supplied sample code. Here's a working console program that uses nodeTypedValue. I hope this helps.

// Base64CPP.cpp : Defines the entry point for the console application.

//  NOTE:
//  This code is provided as is in the form of a sample with no warranties of any kind, 
//  either expressed or implied for any purpose. Use at your own risk.

#include "stdafx.h"

#include <TCHAR.H>
#include <stdio.h>
#include <sys/stat.h>
#include <fstream>
#include <string.h>

#include <atlbase.h>
#import <msxml4.dll> named_guids
using namespace MSXML2;

inline void EVAL_HR( HRESULT _hr ) 
   { if FAILED(_hr) throw(_hr); }

//  Binary to Base64 Encoding
bool DoEncoding(LPCTSTR lpszXMLFile, LPCTSTR lpszBinFile)
{
    bool bRetVal = false;
    try
    {
        long lFileSize;
        struct stat fileSizeVal;

        //  Get the file size
        if (stat(lpszBinFile, &fileSizeVal) == 0)
        {
            lFileSize = fileSizeVal.st_size;
            if(lFileSize <= 0)
                return false;
        }
        else 
            return false;

        //  Instantiate XML DOMDocument
        CComPtr<IXMLDOMDocument2> spXMLDoc;
        CComPtr<MSXML2::IXMLDOMElement> spDataElement;
        HRESULT hr = spXMLDoc.CoCreateInstance(CLSID_DOMDocument40);
        EVAL_HR(hr);
        spXMLDoc->loadXML(_T("<?xml version='1.0' encoding='UTF-8'?> <Data/>"));

        //  Prepare the top node to store binary data as base64
        spDataElement = spXMLDoc->documentElement;
        ATLASSERT(spDataElement != NULL && _T("Failed to get document element."));

        hr = spDataElement->put_dataType(CComBSTR(_T("bin.base64")));
        EVAL_HR(hr);

        //  Read the file into memory
        std::ifstream binDataFile;
        binDataFile.open(lpszBinFile, std::ios::binary);
        binDataFile.seekg(std::ios::beg);
        SAFEARRAY* psa = SafeArrayCreateVector( VT_UI1, 0L, lFileSize);
        binDataFile.read((char*)psa->pvData, lFileSize);
        binDataFile.close();

        //  Save the binary data into Data node
        VARIANT var;
        VariantInit(&var);
        var.parray = psa;
        var.vt = (VT_ARRAY | VT_UI1 );
        spDataElement->nodeTypedValue = var;

        //  Save the XML Document
        spXMLDoc->save(lpszXMLFile);

        bRetVal = true;
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    return bRetVal;
}

//  Base64 to binary decoding
bool DoDecoding(LPCTSTR lpszXMLFile, LPCTSTR lpszBinFile)
{
    bool bRetVal = false;
    try
    {
        //  Instantiate DOMDocument and load XML file
        CComPtr<IXMLDOMDocument2> spXMLDoc;
        CComPtr<MSXML2::IXMLDOMElement> spDataElement;
        HRESULT hr = spXMLDoc.CoCreateInstance(CLSID_DOMDocument40);
        EVAL_HR(hr);
        CComVariant vtFileName = CComBSTR(lpszXMLFile);
        spXMLDoc->load(vtFileName);

        //  ASSUMPTION: documentElement (top element) contains base64 data
        spDataElement = spXMLDoc->documentElement;
        ATLASSERT(spDataElement != NULL && _T("Failed to get document element."));

        //  Prepare the file for writing
        std::ofstream binDataFile (lpszBinFile, std::ios::out | std::ios::binary);

        //  Save the binary data into data file
        long lDataLength=0;
        hr = SafeArrayGetUBound(spDataElement->nodeTypedValue.parray, 1, &lDataLength);
        EVAL_HR(hr);
        lDataLength++;

        binDataFile.write((char*)(spDataElement->nodeTypedValue.parray->pvData), lDataLength);
        binDataFile.close();

        bRetVal = true;
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    return bRetVal;
}

int main(int argc, char* argv[])
{
    if(argc < 4)
    {//insufficient parameters
        printf(_T("\nSample app to encode/decode binary data as base64 XML using MSXML.\n"));
        printf(_T("\nUsage:\tBase64CPP.exe <e>|<d> <XMLFileName> <BinaryDataFile>"));
        printf(_T("\n\nExamples:"));
        printf(_T("\n\tEncode binary data in 1.jpg and save as Base64 into 1.xml:"));
        printf(_T("\n\t\tBase64CPP.exe e c:\\1.xml c:\\1.jpg\n"));
        printf(_T("\n\tDecode base64 data in 1.xml and save as binary into 2.jpg:"));
        printf(_T("\n\t\tBase64CPP.exe d c:\\1.xml c:\\2.jpg\n\n"));
        return -1;
    }

    try
    {
        HRESULT hr = CoInitialize(NULL);
        EVAL_HR(hr);

        if(_tcsicmp(argv[1], _T("e")) == 0)
        {
            if(DoEncoding(argv[2], argv[3]))
                printf(_T("Success. See %s for results."), argv[2]);
            else
                printf(_T("Failed."));
        }
        else
        {
            if(DoDecoding(argv[2], argv[3]))
                printf(_T("Success. See %s for results."), argv[3]);
            else
                printf(_T("Failed."));
        }
    }
    catch(int)
    {
        //TODO: Error handling
        printf(_T("Exception raised!"));
    }

    CoUninitialize();
    getchar();
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文