Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

PRB: Error Occurs When You Open an ADO Recordset on an XML Stream


View products that this article applies to.

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.

↑ Back to the top


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.

↑ Back to the top


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.

↑ Back to the top


Status

This behavior is by design.

↑ Back to the top


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.

↑ Back to the top


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.

↑ Back to the top


Keywords: KB259555, kbprb, kbmsxmlnosweep, kbdatabase

↑ Back to the top

Article Info
Article ID : 259555
Revision : 4
Created on : 10/31/2003
Published on : 10/31/2003
Exists online : False
Views : 528