Реализация XmlTextWriter в новом XmlRecordsetWriter для потоков

Для справки см. Мой вопрос здесь.

Итак, проблема не в том, что я не могу отправить 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
}

}

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
639
2

Ответы 2

Сначала строчка:

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);

Надеюсь, это сработает! На самом деле я написал этот ответ, чтобы завершить его позже, и если я в правильном направлении.

Другие вопросы по теме