Повторное использование класса XmlTextWriter - PullRequest
3 голосов
/ 07 февраля 2011

Можно ли повторно использовать один и тот же экземпляр класса XmlTextWriter для создания большего количества документов XML?Я имею в виду что-то вроде этого:

XmlTextWriter writer = new XmlTextWriter();
writer.WriteStartDocument();
writer.WriteStartElement("Message1");
writer.WriteEndElement();
writer.WriteEndDocument();

// do something with xml created
...

writer.Reset() // ?
writer.WriteStartDocument();
writer.WriteStartElement("Message2");
writer.WriteEndElement();
writer.WriteEndDocument();
// do something with xml created
...

Ответы [ 3 ]

2 голосов
/ 07 февраля 2011

Простой ответ: да, это возможно.

Но это было бы достигнуто, если основной поток не указывает на файл. MemoryStream может быть хорошим примером этого.

Поскольку MemoryStream сохраняет поток «в памяти», вы можете написать множество XML-файлов с помощью вашего XmlTextWriter и после завершения каждого документа выполнить MemoryStream.ToArray () и передать его в качестве аргумента для File.WriteAllBytes.

После записи всех байтов вы очистите поток памяти.

Вы можете очистить поток памяти, вызвав метод MemoryStream.SetLength, и указать 0 в качестве длины:

Подробнее о перегрузке потока в конструкторе XmlTextWriter читайте здесь:

И это для File.WriteAllBytes:

О некоторых проблемах при повторном использовании XmlTextWriter

Несколько лет назад @NigelTouch выразил обеспокоенность по поводу некоторых комментариев:

Проблема, которую я обнаружил, заключается в том, что если исключение выдается на полпути через, например, после WriteStartElement (), тогда даже если вы Flush () Writer и установите длину потока на 0, Writer остается в WriteState элемента. Когда вы начинаете следующий документ, он начинается с закрывающего ">" (например). Избегайте повторного использования

И несколько часов назад @ Mike-EEE попал в ту же проблему:

Пожалуйста, предоставьте рабочий код примера решения. Я сталкиваюсь та же проблема, что описывает Найджел

Кстати, небольшая пробная ошибка заставила меня восстановить данное XmlTextWriter и использовать его столько раз, сколько вы хотите:

    using(MemoryStream stream = new MemoryStream())
    using(StreamReader streamReader = new StreamReader(stream))
    using(XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8))
    {
        writer.WriteStartDocument(true);
        writer.WriteStartElement("a");

        try 
        {
            throw new Exception();
        }
        catch 
        {
            // This line makes de magic: ending the document
            // avoids the issue mentioned by @NigelTouch
            writer.WriteEndDocument();
            writer.Flush();
            stream.SetLength(0);
        }


        writer.WriteStartDocument(true);
        writer.WriteStartElement("b");
        writer.WriteEndElement();
        writer.Flush();

        stream.Position = 0;

        Console.WriteLine(streamReader.ReadToEnd());

    }
1 голос
/ 07 февраля 2011

Класс XmlTextWriter:

Представляет модуль записи, который обеспечивает быстрый, не кэшированный, только для пересылки способ генерации потоков илифайлы, содержащие данные XML, соответствующие W3C Extensible Markup Language (XML) 1.0 и пространствам имен в рекомендациях XML.

(выделено мной)

Класс не предоставляет Reset или любой подобной функции, а также не предоставляет доступ к базовому потоку.Если у вас есть доступ к базовому потоку самостоятельно, вы можете сбросить этот поток самостоятельно.

Все это означает, что невозможно повторно использовать его напрямую.

0 голосов
/ 07 февраля 2011

Я предполагаю, что flush сделает примерно то, что вы просите.Просто создайте и получите XML, сбросьте, введите, повторите;)

Приветствия.

...