你能获得XslCompiledTransform进展吗?

时间:2008-12-16 12:06:22

标签: c# .net file-io xslt

我想读取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 个答案:

答案 0 :(得分:4)

一个选项是从转换​​中发送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);
    }
}