views:

322

answers:

8

In my C# client application, I use XSLT to transform XML into HTML.

I would like to be able to edit these files in place, without having to recompile the entire solution. I'm having trouble working out how to set up Visual Studio 2008 to allow this.

The problem is that the XSLT files must get copied to the output directory somehow. Currently this happens during the build process. (My XSLT files are set to "copy if newer".) The build process can take a few minutes, which seems excessive for making small tweaks to the HTML.

I could make my XSLT edits in the output directory itself, but the output directory is not under source control. I have accidentally wiped out my quick edits several times by building my solution.

I'd like to reduce the cycle time for debugging XSLT, while keeping my XSLT files under source control and preventing accidental overwrites.

Summary of Responses: It appears that the most practical approach for solving this problem -- given that Visual Studio doesn't have a nice way of doing it out of the box -- is to create a separate project that contains the content files. These files get copied to the output location when the project gets built. That way I don't have to compile the whole solution, just the one project with all the static information like XSLT, CSS, images, etc.

Several folks suggested using sync or batch copy tools, but while this would work for me personally, setting it up for the other members of the team too would be a lot of extra work.

+1  A: 

You can edit the file directly in the output folder.

On another note, a lot of people don't know that rich tools are built into VS to allow debugging xslts.

http://msdn.microsoft.com/en-us/library/ms255605%28VS.80%29.aspx

tzerb
The problem with editing the file in the output folder is remembering to update the version inside the solution when you've finished. The version inside the solution is the one under source control.
dthrasher
It's a bit of a hack but you put that file in the project. Could you pick up the file with a relative path? ..\..\folder\file.xslt?
tzerb
A relative path won't work, because the files are at different levels in the tree. And including the XSLT file in the output directory in the project causes problems when you Clean or Rebuild the solution. Good thoughts, though.
dthrasher
+1  A: 

One approach is to include a C# Preprocessor Directive to point my XSLT load function to the solution directory when in debug mode, but the output directory when doing a release build.

Something like:

string viewFolder = AppDomain.CurrentDomain.BaseDirectory;

#if DEBUG
// Move up from /bin/debug
viewFolder = viewFolder + @"..\..\";
#endif

But that feels like a hack.

dthrasher
+3  A: 

I am not entirely clear about your question, but you can instruct Visual Studio to copy the file from the solution to the output folder every time that you build.

Let me try to understand your scenario:

  • You have the XSLT files checked into source control along with your C# code. For example, if your project is in a folder called MyProj, then the XSLT files reside in MyProj/Templates
  • You want to be able to edit the xslt files in the Templates folder and submit those changes to source control just like you do with .cs or other files in your project.
  • You want a copy of your xslt files in the bin/Debug or bin/Release folder along with your executable.

If that is the case, add the XSLT files to your Visual Studio project. Then right click on them, open Properties, and set "Build Action" = "Content" and "Copy to Output Directory" = "Always". Whenever you build your project, the latest copy of the XSLT files will be placed in your bin/Debug or bin/Release directory.

antonm
That's exactly my scenario. I was hoping to find a way to avoid having to set the Build Action and Copy to Output Directory properties for every single XSLT file in my solution. It's also tedious to have to rebuild the entire solution every time I make a minor change to an XSLT file.
dthrasher
You could make a separate project which contains all the XSLT files and outputs to the same place as your C# project. Then all you have to do is rebuild that one project. If you set "Copy to Output Directory" = "Copy if newer" then this will be very fast.Furthermore, if you use a post-build action on your XSLT project to copy all the .xslt files, you don't have to configure them separately:copy $(ProjectDir)/*.xslt $(OutDir)
antonm
Using a post build action on the XSLT files is clever. That will save me a good bit of configuration work. And creating a separate project for the XSLT would reduce the cycle time quite a bit. I'll give that a try.
dthrasher
I like the separate project solution. It plays along with VSs limitation and keeps things neat.
Goran
+1  A: 

One solution that might work for you is to setup a junction to your Templates in your output folder. This would allow you to use the XSLTs directly without copying them to the output folder. A good idea is to ensure (create) the junction as a build action.

Prerequisites:

  • NTFS
  • A tool to create junctions (e.g. junction)
Josef
That might work, but I'd like to avoid any symbolic link magic NTFS voodoo. Even if I understand how to set it up, asking the rest of the team to do it...
dthrasher
junctions are hardly magic and can be automatically created using pre or post build actions. sorry to hear that they're too complicated for your team.
Josef
A: 

Could you use a file synchronization program (e.g. Microsoft SyncToy "is a free application that synchronizes files and folders between locations") to copy the files? This would allow you to avoid the "copy on build" step because the files are automatically copied after saved. Also, if you edited them in the output directory, the changes could be copied back into your source controled directory. Not what the best real time sync program is for this scenario is, but that could be another question.

Kevin Hakanson
+1  A: 
  1. Create a batch file that copies your xslt's from their source-controlled location to all your bin directories (bin/debug bin/release or whatever ones you have defined)
  2. Add the batch file as an External Tool, optionally assigning a keystroke (or chord) to execute the batch file
  3. Edit, run tool (I'd assign a keystroke to this to make this easy), then check your webpage.
Will
+2  A: 

Apparently you're managing two concerns in one project. The first concern is your business logic (instantiating an XSLT transform, calling it to transform some XML content, outputting the HTML result....). The second concern is the Transformation itself.

So why not create a separate project for your xslt sheets? "Building" this project would consist of copying the sheets to the output folder. Changing xslt will not influence the other project, hence reduce the build time.

Separation of Concerns at project level, that is :)

xtofl
You make a good point about separation of concerns. Your suggestion about using a separate project is essentially the same recommendation that @antonmarkov made. I think it's probably the safest route.
dthrasher
A: 

I have exactly the same issue. I have bought a program called ViceVersa (http://www.tgrmn.com/) in which I have setup sync profiles so that my css, layout and xslt folders are synced from my machine to my dev server as soon as any changes are made. If I make any code changes then I just publish as normal.

Josh