PRB: Error Occurs When You Open an ADO Recordset on an XML Stream (259555)
The information in this article applies to:
- ActiveX Data Objects (ADO) 2.5
- ActiveX Data Objects (ADO) 2.6
- ActiveX Data Objects (ADO) 2.7
- Microsoft Data Access Components 2.5
- Microsoft Data Access Components 2.6
- Microsoft Data Access Components 2.7
This article was previously published under Q259555 SYMPTOMS If you persist a Microsoft ActiveX Data Objects (ADO)
recordset into an external XML file, and you then load the XML file into an ADO
Stream object and open another ADO recordset on the ADO Stream object, the
following error messages occurs: Code = E_FAIL
Source = Microsoft OLEDB Persistence Provider Description = Recordset
cannot be created from the specified source. The source file or stream must
contain Recordset data in XML or ADTG format. CAUSE When a recordset is saved to a file in an XML format, the
data written to the file by the Microsoft Persistence Provider is in the UTF-8 encoding charset.
However, the default character set of
an ADO Stream object is Unicode (UTF-16) with byte order mark 0xFFFE. So, when the UTF-8 format file is loaded into the ADO stream, the internal buffer of
the ADO stream contains the UTF-8 data but the data is prepended with 0xFFFE Unicode byte order marks. This causes the XML parser to fail, and
the XML parser does not process the data when the ADO stream is used to open a
recordset.
If the recordset is saved to a Stream in XML format, the
data written to the stream is in Unicode encoding charset, that is, UTF-16, which is the same as the default encoding used for an ADO
stream. RESOLUTION Here are two ways you can work around this problem:
- Save the recordset to an ADO stream and use that to reopen
a new recordset.
- Save the recordset to a file. Before you use a Stream to
open this file, set the Stream's charset property to UTF-8. You can then open
the Stream and use it to reopen a recordset.
Note Usually, the client is responsible for letting the ADO Stream
know what the actual encoding is for the file data.
STATUS This behavior is by design. MORE INFORMATION The following code demonstrates the problem. If the
following code line is uncommented, the code runs without error:
//pStream->Charset = "UTF-8";
Note You may need to change the connection string to reflect your
data source. Note
You must change uid=<username> and pwd=<strong password> to
the correct values before you run this code. Make sure that uid has the
appropriate permissions to perform this operation on the database. Sample Code
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <io.h>
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "ADOEOF")
int main()
{
CoInitialize(NULL);
HRESULT hr = S_OK;
_ConnectionPtr pDBConn;
_RecordsetPtr pRS1,pRS2;
_StreamPtr pStream ;
_variant_t vtEmpty (DISP_E_PARAMNOTFOUND, VT_ERROR);
_bstr_t bstrEmpty(L"");
try
{
struct _finddata_t xml_file;
long hFile;
if( (hFile = _findfirst("c:\\test.xml", &xml_file )) != -1L)
{
DeleteFile("c:\\test.xml");
}
_bstr_t bstrConnect( L"dsn=pubs;uid=<username>;pwd=<strong password>;" );
hr = pDBConn.CreateInstance( __uuidof( Connection ) );
pDBConn->ConnectionString = bstrConnect;
pDBConn->Open( bstrEmpty, bstrEmpty, bstrEmpty,-1 );
hr=pRS1.CreateInstance( __uuidof( Recordset ) );
hr=pRS2.CreateInstance( __uuidof( Recordset ) );
hr=pStream.CreateInstance( __uuidof( Stream ) );
pRS1->Open("Select * from authors",pDBConn.GetInterfacePtr(),adOpenStatic,adLockOptimistic,adCmdText);
pRS1->Save("C:\\test.xml",adPersistXML);
//pStream->Charset = "UTF-8";
pStream->Open(vtEmpty,adModeUnknown,adOpenStreamUnspecified,bstrEmpty, bstrEmpty);
pStream->LoadFromFile("C:\\test.xml");
hr = pRS2->Open(pStream.GetInterfacePtr(),vtEmpty,adOpenStatic, adLockOptimistic,adCmdFile);
// check it out
_variant_t RetVal;
RetVal = pRS2->Fields->Item["au_lname"]->Value;
//Cleanup
pRS1->Close();
pRS2->Close();
pDBConn->Close();
}
catch( _com_error &e )
{
// basic error handling
_tprintf(_T("Exception!\n"));
_tprintf(_T("\a\tCode = %08lx\n"), e.Error());
_tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
_tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
_tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
}
CoUninitialize();
return(0);
}
NOTE: You may notice that if you specify other charsets such as
"iso-8859-1" also works around the problem. For example:
pStream->Charset = "iso-8859-1";
This is because there is no 0xFFFE Unicode byte order marks prepended
to your data when you load the XML file into the ADO Stream object.
REFERENCES For more information, see the MSDN Library documentation
about the ADO Stream object, and the Charset property of the object. The Stream
object is available in ADO 2.5 and later.
Modification Type: | Major | Last Reviewed: | 10/31/2003 |
---|
Keywords: | kbDatabase kbMSXMLnosweep kbprb KB259555 kbAudDeveloper |
---|
|