summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/XslTransform/XslTransform.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/XslTransform/XslTransform.cs')
-rw-r--r--tools/Sandcastle/Source/XslTransform/XslTransform.cs275
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();
+ }
+}