Microsoft KB Archive/259555

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

Article ID: 259555

Article Last Modified on 10/31/2003

-

APPLIES TO


 * Microsoft ActiveX Data Objects 2.5
 * Microsoft ActiveX Data Objects 2.6
 * Microsoft ActiveX Data Objects 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 = &quot;UTF-8&quot;; Note You may need to change the connection string to reflect your data source.

Note You must change uid= and pwd= 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
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 

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&quot;&quot;); try {       struct _finddata_t xml_file; long hFile; if( (hFile = _findfirst(&quot;c:\\test.xml&quot;, &xml_file )) != -1L) {           DeleteFile(&quot;c:\\test.xml&quot;); }       _bstr_t    bstrConnect( L&quot;dsn=pubs;uid= ;pwd= ;&quot; ); 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(&quot;Select * from authors&quot;,pDBConn.GetInterfacePtr,adOpenStatic,adLockOptimistic,adCmdText); pRS1->Save(&quot;C:\\test.xml&quot;,adPersistXML); //pStream->Charset = &quot;UTF-8&quot;; pStream->Open(vtEmpty,adModeUnknown,adOpenStreamUnspecified,bstrEmpty, bstrEmpty); pStream->LoadFromFile(&quot;C:\\test.xml&quot;); hr = pRS2->Open(pStream.GetInterfacePtr,vtEmpty,adOpenStatic, adLockOptimistic,adCmdFile); // check it out _variant_t RetVal; RetVal = pRS2->Fields->Item[&quot;au_lname&quot;]->Value; //Cleanup pRS1->Close; pRS2->Close; pDBConn->Close; }   catch( _com_error &e ) {       // basic error handling _tprintf(_T(&quot;Exception!\n&quot;)); _tprintf(_T(&quot;\a\tCode = %08lx\n&quot;), e.Error); _tprintf(_T(&quot;\a\tCode meaning = %s\n&quot;), e.ErrorMessage); _bstr_t bstrSource(e.Source); _bstr_t bstrDescription(e.Description); _tprintf(_T(&quot;\a\tSource = %s\n&quot;), (LPCTSTR) bstrSource); _tprintf(_T(&quot;\a\tDescription = %s\n&quot;), (LPCTSTR) bstrDescription); }   CoUninitialize; return(0); }
 * 1) import &quot;c:\program files\common files\system\ado\msado15.dll&quot; no_namespace rename(&quot;EOF&quot;, &quot;ADOEOF&quot;)

NOTE: You may notice that if you specify other charsets such as &quot;iso-8859-1&quot; also works around the problem. For example: pStream->Charset = &quot;iso-8859-1&quot;; 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.

