C++ MSXML。将数据作为Base64获取

C++ MSXML。将数据作为Base64获取,c++,xml,base64,msxml,C++,Xml,Base64,Msxml,我使用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 =

我使用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\u元素
。如果我检查这个节点的数据类型,我会得到
VT\u NULL
。因此,我以字符串的形式获取数据


我的代码中有什么错误?

我相信问题不在您提供的示例代码中。下面是一个使用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;
}
//Base64CPP.cpp:定义控制台应用程序的入口点。
//注:
//本规范以样品的形式提供,无任何形式的担保,
//出于任何目的明示或暗示的。使用风险自负。
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
#包括
#导入命名的GUI
使用名称空间MSXML2;
在线无效评估小时(HRESULT小时)
{如果失败(_hr)抛出(_hr);}
//二进制到Base64编码
bool-doencode(LPCTSTR-lpszXMLFile,LPCTSTR-lpszBinFile)
{
bool-bRetVal=false;
尝试
{
长文件大小;
struct stat fileSizeVal;
//获取文件大小
if(stat(lpszBinFile,&fileSizeVal)==0)
{
lFileSize=fileSizeVal.st_size;
if(lFileSize loadXML(_T(“”));
//准备顶部节点以将二进制数据存储为base64
spDataElement=spXMLDoc->documentElement;
ATLASSERT(spDataElement!=NULL&&&u T(“获取文档元素失败”);
hr=spDataElement->put_数据类型(CComBSTR(_T(“bin.base64”));
评估人力资源(HR);
//将文件读入内存
std::ifstream binDataFile;
open(lpszBinFile,std::ios::binary);
seekg(std::ios::beg);
SAFEARRAY*psa=SafeArrayCreateVector(VT_UI1,0L,lFileSize);
read((char*)psa->pvData,lFileSize);
binDataFile.close();
//将二进制数据保存到数据节点
变异变量;
方差(var);
帕雷变量=psa;
变量vt=(vt_数组| vt_UI1);
spDataElement->nodeTypedValue=var;
//保存XML文档
spXMLDoc->save(lpszXMLFile);
bRetVal=真;
}
捕获(整数)
{
//TODO:错误处理
printf(_T(“引发异常!”);
}
返回布雷特瓦尔;
}
//Base64到二进制解码
bool-DoDecoding(LPCTSTR-lpszXMLFile,LPCTSTR-lpszBinFile)
{
bool-bRetVal=false;
尝试
{
//实例化DOMDocument并加载XML文件
CComPtr spXMLDoc;
CComPtr SPDATALEMENT;
HRESULT hr=spXMLDoc.CoCreateInstance(CLSID_DOMDocument40);
评估人力资源(HR);
CComVariant vtFileName=CComBSTR(lpszXMLFile);
spXMLDoc->load(vtFileName);
//假设:documentElement(顶部元素)包含base64数据
spDataElement=spXMLDoc->documentElement;
ATLASSERT(spDataElement!=NULL&&&u T(“获取文档元素失败”);
//准备要写的文件
流binDataFile的std::of(lpszBinFile,std::ios::out | std::ios::binary);
//将二进制数据保存到数据文件中
长lDataLength=0;
hr=SafeArrayGetUBound(spDataElement->nodeTypedValue.parray,1,&lDataLength);
评估人力资源(HR);
lDataLength++;
write((char*)(spDataElement->nodeTypedValue.parray->pvData),lDataLength);
binDataFile.close();
bRetVal=真;
}
捕获(整数)
{
//TODO:错误处理
printf(_T(“引发异常!”);
}
返回布雷特瓦尔;
}
int main(int argc,char*argv[])
{
如果(argc<4)
{//参数不足
printf(_T(“\n使用MSXML将二进制数据编码/解码为base64 XML的示例应用程序。\n”);
printf(_T(“\n用法:\tBase64CPP.exe”);
printf(_T(“\n\n示例:”);
printf(_T(“\n\T将二进制数据编码到1.jpg中,并另存为Base64到1.xml:”);
printf(_T(“\n\T\tBase64CPP.exe ec:\\1.xml c:\\1.jpg\n”);
printf(_T(“\n\T将base64数据编码为1.xml并另存为二进制文件到2.jpg:”);
printf(_T(“\n\T\tBase64CPP.exe d c:\\1.xml c:\\2.jpg\n\n”);
返回-1;
}
尝试
{
HRESULT hr=协同初始化(NULL);
评估人力资源(HR);
如果(_tcsicmp(argv[1],_T(“e”)==0)
{
if(不编码(argv[2],argv[3]))
printf(_T(“成功。有关结果,请参见%s”),argv[2]);
其他的
printf(_T(“失败”);
}
其他的
{
if(十二进制编码(argv[2],argv[3]))
printf(_T(“成功。有关结果,请参见%s”),argv[3]);
其他的
printf(_T(“失败”);
}
}
捕获(整数)
{
//TODO:错误处理
printf(_T(“引发异常!”);
}
coninitialize();
getchar();
返回0;
}