Вы можете получить прогресс XmlCompiledTransform? - PullRequest
4 голосов
/ 16 декабря 2008

Я хочу прочитать XML-файл, применить преобразование, а затем записать в другой файл. Лучший способ, которым я могу придумать, это:

using (XmlTextReader reader = new XmlTextReader(new FileStream(_source, FileMode.Open)))
using (XmlTextWriter writer = new XmlTextWriter(new StreamWriter(_destination)))
{
   _xslTransform.Transform(reader, writer);
}

Но я действительно хочу добиться прогресса. Если я просто копирую данные, я могу сделать что-то вроде этого (это может быть не на 100% правильно, а что-то вроде этого):

using (BinaryReader reader = new BinaryReader(new FileStream(_source, FileMode.Open)))
using (BinaryWriter writer = new StreamWriter(_destination))
{
    byte[] buffer = new byte[2048];
    int read = 0;
    int actual = 0;
    long total = reader.BaseStream.Length;

    while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
    {
        writer.Write(buffer, 0, read);
        actual = (actual <= total ? actual + read : read);
        updateProgress(Convert.ToInt32(actual / total * 100));
    }
}

Так есть ли способ сделать это при использовании XslCompiledTransform. Я мог бы просто прочитать его в память перед записью в файл, но я хочу ограничить объем используемой памяти, или XslCompiledTransform загружает все это в память?

Надеюсь, в этом есть какой-то смысл, спасибо!

Адам.

1 Ответ

4 голосов
/ 16 декабря 2008

Можно отправить сообщения xsl: message изнутри преобразования и прослушать эти сообщения.

При таком подходе вы должны сначала выполнить входной документ и сосчитать узлы, по которым ваше преобразование "перебирает". Это можно сделать с помощью очень простого XSLT, который просто отправляет сообщение на каждый интересующий узел.

Затем - во время фактического преобразования - каждый раз, когда вы нажимаете на интересующий вас узел, вы можете отправить

<xsl:message terminate="no">progress:mynode</xsl:message>

сообщение о прогрессе.

Это сообщение может быть перехвачено в вызывающем коде C # с помощью прослушивателя сообщений. Вы можете поместить следующий код в небольшой класс для применения XSL-преобразования. Это просто базовый пример для иллюстрации; Я надеюсь, вы поняли:

protected event MessageListener progressMessageIntercepted;

public void AddProgressMessageListener(MessageListener listener)
{
    progressMessageIntercepted += listener;
}

public void RemoveMessageListeners()
{
    progressMessageIntercepted = null;
}

protected void MessageCallBack(object sender, XsltMessageEncounteredEventArgs e)
{
    if (e.Message.StartsWith("progress:"))
    {
        if (progressMessageIntercepted != null)
        {
            progressMessageIntercepted(this, null);
        }
    }
}

protected void Transform(string inputFile, string outputFile, string xsltFile)
{
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(xsltFile);
    XsltArgumentList parameters = new XsltArgumentList();
    parameters.XsltMessageEncountered += new XsltMessageEncounteredEventHandler(MessageCallBack);

    using (XmlWriter xmlWriter = XmlWriter.Create(outputFile))
    {
        xslt.Transform(inputFile, parameters, xmlWriter);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...