How to avoid compiling xsl file everytime invoking XslCompiledTransform.Transform?

hi,

I am using XslCompiledTransform.Transform function to transform an xml into another xml file using an XSL.
When I invoke the Transform function it is taking several minutes everytime to compile the xsl file.

Is there any way to save the compiled xsl and use the compiled version when invoking Transform function?

Thanks for any help.
ipjyoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

käµfm³d 👽Commented:
The Load() method of XslCompiledTransform actually compiles the stylesheet. As long as you maintain a reference to the original object and do not call Load() again, then the stylesheet should remain compiled.
0
ipjyoAuthor Commented:
Thanks for the useful information.

I dont maintain a reference to the original object.
I have the transform function defined in another project and I am referencing that assembly and invoking a method called DoTransform() with two parameters (XSL, XML) which in turn does the load and transform methods.
Is it possible to serialize the compiled XSL transform and when I invoke DoTransform() it will check if the xsl that is passed to DoTransform() and the deserialized xsl are same. If they are same avoid Load() otherwise Load() again. Is this scenario possible?

Thanks for the help.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

käµfm³d 👽Commented:
I'm not sure. But to me, that sounds overly complicated.

It seems to me that you have multiple stylesheets that you want to be able to call on demand without having to compile them each time they are used. The following could be a potential solution, but depending on how many stylesheets you have, could use a good bit of memory (change "outfile.xml" to fit your situation):
public class TransformClass
{
    private Dictionary<string, XslCompiledTransform> transformers;

    public TransformClass()
    {
        this.transformers = new Dictionary<string, XslCompiledTransform>();
    }

    public void DoTransform(string xsl, string xml)
    {
        if (!this.transformers.Keys.Contains(xsl))
        {
            this.transformers.Add(xsl, new XslCompiledTransform());
            this.transformers[xsl].Load(xsl);
        }

        this.transformers[xsl].Transform(xml, "outfile.xml");
    }
}

Open in new window

0
käµfm³d 👽Commented:
Looking back, I suppose the above is what you described...   the mention of "serialization" threw me off a bit   :)
0
ipjyoAuthor Commented:
Hi,
My requirement is similar to what you have suggested.
Based on the description and code above, My understanding is that when a particular xsl is modified and invoke DoTransform() I need to pass a new key associated with the modified xsl and then load that xsl into the dictionary with that new key.

I am more concerned about what happens when the stylesheet is modified rather than being able to maintain multiple stylesheets? How would I know if it is modified from the previous version? I need to be able to compile the xsl only when it is modified.

Thank you.
0
ipjyoAuthor Commented:
I was also reading the link you provided.
It says "especially for server applications, to cache an XslCompiledTransform instance if the same stylesheet is likely to be executed again."

If you have any idea Could you tell me how to implement caching mechanism in windows application?
Thanks.
0
käµfm³d 👽Commented:
The path to the XSL is what I used as the key--you can of course use whatever key you like, but I thought the path would be unique between stylesheets.

As to modifications...   Even if you maintain one XslCompiledTransform object, how would it know that the stylesheet has change? Without calling the Load() method each time, the XslCompiledTransform object is going to have the last stylesheet it was given compiled into memory when you call Transform().

Unless someone can speak otherwise, my guess would be that you would need to keep track of when your XSL changes. You could probably get away with some checksum'ing:
public class TransformClass
{
    private byte[] stylesheetChecksum;
    private XslCompiledTransform transformer;

    public TransformClass()
    {
        this.transformer = new XslCompiledTransform();
    }

    public void DoTransform(string xsl, string xml)
    {
        byte[] incomingChecksum = GetStylesheetChecksum(xsl);

        if (this.stylesheetChecksum == null)
        {
            this.stylesheetChecksum = incomingChecksum;
        }

        if (!CompareCheckSums(incomingChecksum))
        {
            this.transformer.Load(xsl);
        }

        this.transformer.Transform(xml, "outfile.xml");
    }

    private byte[] GetStylesheetChecksum(string XSL)
    {
        byte[] hash;

        using (System.IO.FileStream stylesheet = new System.IO.FileStream(XSL, System.IO.FileMode.Open))
        {
            System.Security.Cryptography.MD5 checksum = new System.Security.Cryptography.MD5CryptoServiceProvider();
            hash = checksum.ComputeHash(stylesheet);
        }

        return hash;
    }

    private bool CompareCheckSums(byte[] newCheckcsum)
    {
        if (this.stylesheetChecksum.Length != newCheckcsum.Length) return false;

        for (int i = 0; i < newCheckcsum.Length; i++)
        {
            if (this.stylesheetChecksum[i] != newCheckcsum[i])
            {
                return false;
            }
        }

        return true;
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
käµfm³d 👽Commented:
Slight modification to my DoTransform() above:
public void DoTransform(string xsl, string xml)
{
    byte[] incomingChecksum = GetStylesheetChecksum(xsl);

    if (this.stylesheetChecksum == null)
    {
        this.stylesheetChecksum = incomingChecksum;
        this.transformer.Load(xsl);
    }

    if (!CompareCheckSums(incomingChecksum))
    {
        this.transformer.Load(xsl);
    }

    this.transformer.Transform(xml, "outfile.xml");
}

Open in new window

0
ipjyoAuthor Commented:
Thank you very much for all your help.
I appreciate your help on this post.



0
käµfm³d 👽Commented:
NP.  I enjoy assisting others when I can  :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.