 |
|
 |
Since the transformation uses .NET, does it support XSLT 2.0?
|
|
|
|
 |
|
 |
Yes, in fact the VS2005 download is built against .Net 2. If you compare the VS2003 and VS2005 versions you will see that the XslTransform and XslCompiledTransform objects are used respectively.
|
|
|
|
 |
|
 |
Hmm, interesting. I remember reading (e.g., [a href=http://p2p.wrox.com/topic.asp?TOPIC_ID=44500]here[/a] that .NET 2 does not support XSLT 2.0. I guess I should just try it out and see...
|
|
|
|
 |
|
 |
Opps. I misread your question. AFAIK Saxon.Net supports XSLT 2, so this tool could easily be changed to use the Saxon transformer to support XSLT 2 transformations.
|
|
|
|
 |
|
 |
Easily? I don't think so. I spent half a day trying to get it to work, and failed. Not really surprised, considering it's Java-based and uses a .NET Java VM. In the end, I went with Altova XML engine, which is free and works beautifully. Here's the code:
public override string DoGenerateCode(string inputFileName, string inputFileContent)
{
string transformerFileName = "NOT FOUND";
string result;
try
{
FileInfo inputFileInfo = new FileInfo(inputFileName);
XmlDocument sourceDocument = new XmlDocument();
sourceDocument.LoadXml(inputFileContent);
string transformerFile = sourceDocument.DocumentElement.Attributes["transformer"].Value;
if (!File.Exists(transformerFileName))
{
transformerFileName = Path.Combine(inputFileInfo.DirectoryName, transformerFile);
if (!File.Exists(transformerFileName))
{
FileInfo assemblyFileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
transformerFileName = Path.Combine(assemblyFileInfo.DirectoryName, transformerFile);
}
}
FileInfo fi = new FileInfo(inputFileName);
AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
ApplicationClass c = new ApplicationClass();
IXSLT2 x = c.XSLT2;
x.InputXMLFileName = inputFileName;
x.XSLFileName = transformerFileName;
result = x.ExecuteAndGetResultAsString();
}
catch (Exception ex)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("/*");
sb.AppendLine("\tERROR: Unable to generate output for template:");
sb.AppendFormat("\t'{0}'{1}", inputFileName, Environment.NewLine);
sb.AppendLine("\tUsing transformer:");
sb.AppendFormat("\t'{0}'{1}", transformerFileName, Environment.NewLine);
sb.AppendLine("");
sb.AppendLine(ex.ToString());
sb.AppendLine("*/");
result = sb.ToString();
}
return result;
}
|
|
|
|
 |
|
|
 |
|
 |
I have re-written the tool and have published it here. Take a look!
|
|
|
|
 |
|
 |
Great job! I gave you a 5 for your follow up article!
|
|
|
|
 |
|
 |
Is it possible to generate more than one outputfile? Lets say I have a Labels.xml fiel and I want to generate both Label.IDs.cs Label.Strings.cs?
Does the custom tool architechture support it or is always one-to-one ampping required?
BR // Jonas
|
|
|
|
 |
|
 |
In this example no, but it is possible. The custom tool would need to be enhanced to support this.
The custom tool functionality provided in Visual Studio does support the output of multiple files.
|
|
|
|
 |
|
 |
OK, what a petty... Currently, I have an XML file in my project that I transform into various files using diffrent XSLT-scripts. In order to generate more than one file, I have a custom build rule and a BAT-script to invoke the XSLT-transformer. The drawback is that one people are to add their xml-files to their project, the job of making sure that the script is called appropriatelly is confusing...
A possible (but ugly) solution may be to let MyTransformCodeGenerator::DoGenerateCode() return _one_ of the generated files and generate the rest of the files without that the visual studio fwk knows about it. This way I would have a deployable code generateor, anyway.
Any other ideas?
// Jonas
|
|
|
|
 |
|
 |
It would certainly be a useful enhancement. One that I could use myself.
I'll see whether I can do this and update the article accordingly.
|
|
|
|
 |
|
 |
I'm trying to do it at the moment. Since we only get a single file with IVsSingleFileGenerator, it looks like we have to use the EnvDTE API in order to add files manually.
|
|
|
|
 |
|
 |
Correct, on further investigation into it, I found an example of multi-file output in the StringResourceTool custom tool. http://wah.onterra.net/blog/archive/2004/12/09/190.aspx
Checkout the GenerateCode() method in the SRCodeGenerator.cs file to see how it's done.
I guess the "difficulty" will be how determine whether the generation is to produce 1 or multiple files. Perhaps additional attributes on the root element will need to be introduced or a special child-element of the root, so that the generation code can branch accordingly.
e.g.
="1.0"
<Root>
-->
<TransformCodeGenerator>
<Transform xslt="abc.xslt" />
<Transform xslt="def.xslt" />
<Transform xslt="hij.xslt" />
</TransformCodeGenerator>
-->
</Root>
|
|
|
|
 |
|
 |
What I had in mind wasn't exactly this. It was, rather, the idea of using XSLT's built-in capability to produce multiple files from a single stylesheet. I know that I am complicating the matter, since one can always make more XSLT files. And besides, even the Altova .NET package does not have the API to do it (though it works perfectly well from the command line).
I will look at the StringResourceTool now.
|
|
|
|
 |
|
 |
Hi Chris,
I am pretty new to xml and xslt and have a requirement to convert a set of Winform controls to a generic class that instantiates these controls. The controls can be used with ASP.NET although they do not support the designer.
What I am trying to figure out is how do I take the controls from a Winform and then create a class which instantiates the objects and their properties....
For example:
I want the form code to come out like this:
using MyNamespace.CustomControls
public myNewClass
{
private CustomControl1 myControl = new CustomControl1();
private CustomControl1.SubControl mySubControl1 = new CustomControl1.SubControl();
myControl.ViewerPreferences.ShowToolBar = true; // value from the form...
mySubControl1.Location = new Size(100, 100); // value from the form...
public myNewClass()
{
}
)
That's pretty much all that is needed but I have no idea where to start. If you could point me in the right direction I sure would be greatful.
Thank you
Christopher Schick
|
|
|
|
 |
|
 |
I will email you directly...
|
|
|
|
 |
|
 |
Chris
Great article! Would you happen to have any more XSLT Templates that would so more examples around Data Objects? I am looking for how to actually persist the DataTable that is generated to a SQL Server Table....was hoping that you had some examples or templates already built. Otherwise any good suggestion of how to proceed would be appreciated.
Thx
Scott
ST
|
|
|
|
 |
|
 |
Nice strategy and tool, and a quick ramp-up time. I spent a day reviewing the XSLT/XPath reference and tutorials, and then another day experimenting with XML based business rules and the resulting generated code. I used another tool, XMLWriter, to do the editing, debugging and transformations (MSXML 4.0 based)/code generation. I found that dynamic class structure generation was a breeze which included XML driven property definitions, collection assignments and class instantiations. As you showed, dynamic UI could also be integrated if desired. I generated source code for design time compilation, but could have easily compiled at runtime using the .NET transformation and compilation capabilities.
This approach differs from my reflection experiments which required predefined classes to be in place before objects could be instantiated based on XML data.
Marc Clifton’s XMLCompiler (CodeCom based) appears to be a nice tool. I am not sure if you can dynamically create classes definitions with it (…for dynamic UI applications there is little need). I am playing around with his data binding code to automatically bind my generated business rules to the UI (generated or static).
Also, an open source project EXSLT has some nice XLST extensions such as regex and other capabilities. You might take a look at that.
Thanks for highlighting this capability.
Ross Anderson
|
|
|
|
 |
|
 |
It doesn't stop there... with the ability to pass in your own extension functions (classes written in .Net) to the XSLTransform, the sky is the limit. You would need to modify the code of the custom tool though, to pass in instances of your extension class.
|
|
|
|
 |
|
 |
Chris
Nice approach.
If you haven't already seen,Kathleen Dollard wrote an excellent book, although complex,entitled Code Generation in Microsoft.NET, published by Apress. She has a web site covering all the source code etc at http://www.gendotnet.com
She has demonstrated a similar approach to what you have taken
using XSLT, codedom etc with a framework and test harness.
Just thought it might be of interest to you
Signing Off....
ByteGhost
|
|
|
|
 |
|
 |
Thanks for the link. Looks like a book worth reading!
|
|
|
|
 |
|
 |
By popular request, I've added downloads for Visual Studio 2003 aswell.
-- Chris
|
|
|
|
 |
|
|
 |
|
 |
I guess the downside for my approach is that with CodeDOM you can write one version which generates code in a variety of languages whereas here you would have to create a different transform.
|
|
|
|
 |