diff options
Diffstat (limited to 'tools/Sandcastle/Source/XslTransform/XslTransform.cs')
-rw-r--r-- | tools/Sandcastle/Source/XslTransform/XslTransform.cs | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/XslTransform/XslTransform.cs b/tools/Sandcastle/Source/XslTransform/XslTransform.cs new file mode 100644 index 0000000..6b6d76c --- /dev/null +++ b/tools/Sandcastle/Source/XslTransform/XslTransform.cs @@ -0,0 +1,275 @@ +// Copyright © Microsoft Corporation. +// This source file is subject to the Microsoft Permissive License. +// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. +// All other rights reserved. + +using System; +using System.IO; +using System.Xml; +using System.Xml.Xsl; +using Microsoft.Ddue.Tools.CommandLine; + + +namespace Microsoft.Ddue.Tools +{ + public class XslTransformer + { + public static int Main(string[] args) + { + // specify options + OptionCollection options = new OptionCollection(); + options.Add(new SwitchOption("?", "Show this help page.")); + options.Add(new ListOption("xsl", "Sepcify transform files.", "xsltPath")); + options.Add(new ListOption("arg", "Sepcify arguments.", "name=value")); + options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath")); + options.Add(new SwitchOption("w", "Do not ignore insignificant whitespace. By default insignificant whitespace is ignored.")); + + ConsoleApplication.WriteBanner(); + + // process options + ParseArgumentsResult results = options.ParseArguments(args); + if (results.Options["?"].IsPresent) + { + Console.WriteLine("XslTransformer xsl_file [xml_file] [options]"); + options.WriteOptionSummary(Console.Out); + return (0); + } + + // check for invalid options + if (!results.Success) + { + results.WriteParseErrors(Console.Out); + return (1); + } + + // check for missing or extra assembly directories + if (results.UnusedArguments.Count != 1) + { + Console.WriteLine("Specify one input XML input file."); + return (1); + } + + if (!results.Options["xsl"].IsPresent) + { + Console.WriteLine("Specify at least one XSL transform file."); + return (1); + } + + // set whitespace setting + bool ignoreWhitespace = !results.Options["w"].IsPresent; + + // Load transforms + string[] transformFiles = (string[])results.Options["xsl"].Value; + XslCompiledTransform[] transforms = new XslCompiledTransform[transformFiles.Length]; + for (int i = 0; i < transformFiles.Length; i++) + { + string transformFile = Environment.ExpandEnvironmentVariables(transformFiles[i]); + transforms[i] = new XslCompiledTransform(); + XsltSettings transformSettings = new XsltSettings(true, true); + try + { + transforms[i].Load(transformFile, transformSettings, new XmlUrlResolver()); + } + catch (IOException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message)); + return (1); + } + catch (UnauthorizedAccessException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message)); + return (1); + } + catch (XsltException e) + { + if (e.InnerException != null) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.InnerException.Message)); + } + else + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.Message)); + } + return (1); + } + catch (XmlException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' is not well-formed. The error is: {1}", transformFile, e.Message)); + return (1); + } + } + + // Compose the arguments + XsltArgumentList arguments = new XsltArgumentList(); + if (results.Options["arg"].IsPresent) + { + string[] nameValueStrings = (string[])results.Options["arg"].Value; + foreach (string nameValueString in nameValueStrings) + { + string[] nameValuePair = nameValueString.Split('='); + if (nameValuePair.Length != 2) continue; + arguments.AddParam(nameValuePair[0], String.Empty, nameValuePair[1]); + } + } + + string input = Environment.ExpandEnvironmentVariables(results.UnusedArguments[0]); + + // prepare the reader + XmlReaderSettings readerSettings = new XmlReaderSettings(); + readerSettings.IgnoreWhitespace = ignoreWhitespace; + + // Do each transform + for (int i = 0; i < transforms.Length; i++) + { + ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Applying XSL transformation '{0}'.", transformFiles[i])); + + // get the transform + XslCompiledTransform transform = transforms[i]; + + // figure out where to put the output + string output; + if (i < (transforms.Length - 1)) + { + try + { + output = Path.GetTempFileName(); + File.SetAttributes(output, FileAttributes.Temporary); + } + catch (IOException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create a temporary file. The error message is: {0}", e.Message)); + return (1); + } + } + else + { + if (results.Options["out"].IsPresent) + { + output = Environment.ExpandEnvironmentVariables((string)results.Options["out"].Value); + } + else + { + output = null; + } + } + + // create a reader + Stream readStream; + try + { + readStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); + } + catch (IOException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message)); + return (1); + } + catch (UnauthorizedAccessException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message)); + return (1); + } + + using (XmlReader reader = XmlReader.Create(readStream, readerSettings)) + { + // create a writer + Stream outputStream; + if (output == null) + { + outputStream = Console.OpenStandardOutput(); + } + else + { + try + { + outputStream = File.Open(output, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete); + } + catch (IOException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message)); + return (1); + } + catch (UnauthorizedAccessException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message)); + return (1); + } + } + + using (XmlWriter writer = XmlWriter.Create(outputStream, transform.OutputSettings)) + { + try + { + // do the deed + transform.Transform(reader, arguments, writer); + } + catch (XsltException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured during the transformation. The error message is: {0}", + (e.InnerException == null) ? e.Message : e.InnerException.Message)); + return (1); + } + catch (XmlException e) + { + ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' is not well-formed. The error is: {1}", input, e.Message)); + return (1); + } + } + } + + // if the last input was a temp file, delete it + if (i > 0) + { + // Console.WriteLine("deleting {0}", input); + try + { + File.Delete(input); + } + catch (IOException e) + { + ConsoleApplication.WriteMessage(LogLevel.Warn, String.Format("The temporary file '{0}' could not be deleted. The error message is: {1}", input, e.Message)); + } + } + + // the last output file is the next input file + input = output; + + } + + return (0); + } + } + + internal class TransformInfo + { + public TransformInfo(string file) + { + this.file = file; + transform.Load(file, settings, resolver); + } + + private string file; + + private XslCompiledTransform transform = new XslCompiledTransform(); + + public string File + { + get + { + return (file); + } + } + + public XslCompiledTransform Transform + { + get + { + return (transform); + } + } + + private static XsltSettings settings = new XsltSettings(true, true); + + private static XmlUrlResolver resolver = new XmlUrlResolver(); + } +} |