Для справки см. Мой вопрос здесь.
Итак, проблема не в том, что я не могу отправить DataSet в классический ASP, а в том, что он ничего не может с ним сделать. Итак, я нашел код для создания xml-структуры набора записей из DataSet.
Я немного подправил его по сравнению с оригинальным источник. Проблема в том, что я не могу извлечь базовый поток и использовать его вместо записи в файл. Что мне не хватает?
Вот как я пытаюсь протестировать класс:
[Test]
public void TestWriteToStream()
{
MemoryStream theStream = new MemoryStream();
XmlRecordsetWriter theWriter = new XmlRecordsetWriter(theStream);
theWriter.WriteRecordset( SomeFunctionThatReturnsADataSet() );
theStream = (MemoryStream)theWriter.BaseStream;
string xmlizedString = UTF8ByteArrayToString(theStream.ToArray());
xmlizedString = xmlizedString.Substring(1);
//Assert.AreEqual(m_XMLNotNull, xmlizedString);
Console.WriteLine(xmlizedString);
}
Вот мой класс:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
namespace Core{
public class XmlRecordsetWriter : XmlTextWriter
{
#region Constructors
// Constructor(s)
public XmlRecordsetWriter(string filename) : base(filename, null) { SetupWriter(); }
public XmlRecordsetWriter(Stream s) : base(s, null) { SetupWriter(); }
public XmlRecordsetWriter(TextWriter tw) : base(tw) { SetupWriter(); }
protected void SetupWriter()
{
base.Formatting = Formatting.Indented;
base.Indentation = 3;
}
#endregion
#region Methods
// WriteRecordset
public void WriteRecordset(DataSet ds) { WriteRecordset(ds.Tables[0]); }
public void WriteRecordset(DataSet ds, string tableName) { WriteRecordset(ds.Tables[tableName]); }
public void WriteRecordset(DataView dv) { WriteRecordset(dv.Table); }
public void WriteRecordset(DataTable dt)
{
WriteStartDocument();
WriteSchema(dt);
WriteContent(dt);
WriteEndDocument();
}
// WriteStartDocument
public void WriteStartDocument()
{
base.WriteStartDocument();
base.WriteComment("Created by XmlRecordsetWriter");
base.WriteStartElement("xml");
base.WriteAttributeString("xmlns", "s", null, "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");
base.WriteAttributeString("xmlns", "dt", null, "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");
base.WriteAttributeString("xmlns", "rs", null, "urn:schemas-microsoft-com:rowset");
base.WriteAttributeString("xmlns", "z", null, "#RowsetSchema");
}
// WriteSchema
public void WriteSchema(DataSet ds) { WriteSchema(ds.Tables[0]); }
public void WriteSchema(DataSet ds, string tableName) { WriteSchema(ds.Tables[tableName]); }
public void WriteSchema(DataView dv){ WriteSchema(dv.Table); }
public void WriteSchema(DataTable dt)
{
// Open the schema tag (XDR)
base.WriteStartElement("s", "Schema", null);
base.WriteAttributeString("id", "RowsetSchema");
base.WriteStartElement("s", "ElementType", null);
base.WriteAttributeString("name", "row");
base.WriteAttributeString("content", "eltOnly");
// Write the column info
int index=0;
foreach(DataColumn dc in dt.Columns)
{
index ++;
base.WriteStartElement("s", "AttributeType", null);
base.WriteAttributeString("name", dc.ColumnName);
base.WriteAttributeString("rs", "number", null, index.ToString());
base.WriteEndElement();
}
// Close the schema tag
base.WriteStartElement("s", "extends", null);
base.WriteAttributeString("type", "rs:rowbase");
base.WriteEndElement();
base.WriteEndElement();
base.WriteEndElement();
}
// WriteContent
public void WriteContent(DataSet ds) { WriteContent(ds.Tables[0]); }
public void WriteContent(DataSet ds, string tableName) { WriteContent(ds.Tables[tableName]); }
public void WriteContent(DataView dv) { WriteContent(dv.Table); }
public void WriteContent(DataTable dt)
{
// Write data
base.WriteStartElement("rs", "data", null);
foreach(DataRow row in dt.Rows)
{
base.WriteStartElement("z", "row", null);
foreach(DataColumn dc in dt.Columns)
base.WriteAttributeString(dc.ColumnName, row[dc.ColumnName].ToString());
base.WriteEndElement();
}
base.WriteEndElement();
}
// WriteEndDocument
public void WriteEndDocument()
{
base.WriteEndDocument();
base.Flush();
base.Close();
}
#endregion
}
}





Сначала строчка:
theStream = (MemoryStream)theWriter.BaseStream;
является избыточным, поскольку MemoryStream уже должен быть основным потоком для записывающего устройства.
Похоже, вы хотите:
theWriter.Close();
theStream.Position = 0; // So you can start reading from the begining
string xml = null;
using (StringReader read = new StringReader(theStream))
{
xml = read.ReadToEnd();
}
Тогда xml будет вашей xml-строкой, которую вы можете загрузить в XPathDocument или XmlDocument и играть, как хотите.
Я думаю, вы хотите работать с объектами на основе данных и данными на основе XML.
Если это правда, я предлагаю использовать классы ADODB (они есть в справочниках COM: Microsoft ActiveX Data Objects 6.0 Library - или в других версиях, таких как 2.8-).
Вы можете преобразовать свой DataTable в ADODB.Recordset с помощью этого кода: Простейший код для преобразования ADO.NET DataTable в ADODB.Recordset.
Итак, у вас есть метод ConvertToRecordset() для использования в следующем коде.
Теперь вам нужен только метод save() для вашего XML-файла:
using ADODB;
using System;
using System.Data;
using System.IO;
namespace ConsoleApplicationTests
{
class Program
{
static void Main(string[] args)
{
Recordset rs = new Recordset();
DataTable dt = sampleDataTable(); //-i. -> SomeFunctionThatReturnsADataTable()
//-i. Convert DataTable to Recordset
rs = ConvertToRecordset(dt);
//-i. Sample Output File
String filename = @"C:\yourXMLfile.xml";
FileStream fstream = new FileStream(filename, FileMode.Create);
rs.Save(fstream, PersistFormatEnum.adPersistXML);
}
}
}
Сила ADODB.Recordset заключается в том, что вы можете очень легко открыть сохраненный XML-файл:
rs.Open(fstream);
Надеюсь, это сработает! На самом деле я написал этот ответ, чтобы завершить его позже, и если я в правильном направлении.