/// <summary> /// Executes the task. /// </summary> /// <exception cref="BuildException"> /// <list type="bullet"> /// <item> /// <description>If the <see cref="OutputFile"/> attribute is set and the <see cref="InFiles"/> element is used.</description> /// </item> /// <item> /// <description>If no source files are present.</description> /// </item> /// <item> /// <description>If the xslt file does not exist.</description> /// </item> /// <item> /// <description>If the xslt file cannot be retrieved by the specified URI.</description> /// </item> /// </list> /// </exception> protected override void ExecuteTask() { // ensure base directory is set, even if fileset was not initialized // from XML if (InFiles.BaseDirectory == null) { InFiles.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } StringCollection srcFiles = null; if (SrcFile != null) { srcFiles = new StringCollection(); srcFiles.Add(SrcFile.FullName); } else if (InFiles.FileNames.Count > 0) { if (OutputFile != null) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1148")), Location); } srcFiles = InFiles.FileNames; } if (srcFiles == null || srcFiles.Count == 0) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1147")), Location); } if (XsltFile.IsFile) { FileInfo fileInfo = new FileInfo(XsltFile.LocalPath); if (!fileInfo.Exists) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1149"), fileInfo.FullName), Location); } } else { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(XsltFile); if (Proxy != null) { request.Proxy = Proxy.GetWebProxy(); } HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode != HttpStatusCode.OK) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1149"), XsltFile), Location); } } foreach (string srcFile in srcFiles) { string destFile = null; if (OutputFile != null) { destFile = OutputFile.FullName; } if (String.IsNullOrEmpty(destFile)) { // TODO: use System.IO.Path (gs) // append extension if necessary string ext = Extension.IndexOf(".") > -1 ? Extension : "." + Extension; int extPos = srcFile.LastIndexOf('.'); if (extPos == -1) { destFile = srcFile + ext; } else { destFile = srcFile.Substring(0, extPos) + ext; } destFile = Path.GetFileName(destFile); } FileInfo srcInfo = new FileInfo(srcFile); FileInfo destInfo = new FileInfo(Path.GetFullPath(Path.Combine( DestDir.FullName, destFile))); if (!srcInfo.Exists) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1150"), srcInfo.FullName), Location); } bool destOutdated = !destInfo.Exists || srcInfo.LastWriteTime > destInfo.LastWriteTime; if (!destOutdated && XsltFile.IsFile) { FileInfo fileInfo = new FileInfo(XsltFile.LocalPath); destOutdated |= fileInfo.LastWriteTime > destInfo.LastWriteTime; } if (destOutdated) { XmlReader xmlReader = null; XmlReader xslReader = null; TextWriter writer = null; try { // store current directory string originalCurrentDirectory = Directory.GetCurrentDirectory(); // initialize XPath document holding input XML XPathDocument xml = null; try { // change current directory to directory containing // XSLT file, to allow includes to be resolved // correctly Directory.SetCurrentDirectory(srcInfo.DirectoryName); // load the xml that needs to be transformed Log(Level.Verbose, "Loading XML file '{0}'.", srcInfo.FullName); xmlReader = CreateXmlReader(new Uri(srcInfo.FullName)); xml = new XPathDocument(xmlReader); } finally { // restore original current directory Directory.SetCurrentDirectory(originalCurrentDirectory); } // initialize xslt parameters XsltArgumentList xsltArgs = new XsltArgumentList(); // set the xslt parameters foreach (XsltParameter parameter in Parameters) { if (IfDefined && !UnlessDefined) { xsltArgs.AddParam(parameter.ParameterName, parameter.NamespaceUri, parameter.Value); } } // create extension objects foreach (XsltExtensionObject extensionObject in ExtensionObjects) { if (extensionObject.IfDefined && !extensionObject.UnlessDefined) { object extensionInstance = extensionObject.CreateInstance(); xsltArgs.AddExtensionObject(extensionObject.NamespaceUri, extensionInstance); } } try { if (XsltFile.IsFile) { // change current directory to directory containing // XSLT file, to allow includes to be resolved // correctly FileInfo fileInfo = new FileInfo(XsltFile.LocalPath); Directory.SetCurrentDirectory(fileInfo.DirectoryName); } // load the stylesheet Log(Level.Verbose, "Loading stylesheet '{0}'.", XsltFile); xslReader = CreateXmlReader(XsltFile); // create writer for the destination xml writer = CreateWriter(destInfo.FullName); // do the actual transformation Log(Level.Info, "Processing '{0}' to '{1}'.", srcInfo.FullName, destInfo.FullName); XslCompiledTransform xslt = new XslCompiledTransform(); string xslEngineName = xslt.GetType().Name; Log(Level.Verbose, "Using {0} to load '{1}'.", xslEngineName, XsltFile); xslt.Load(xslReader, new XsltSettings(true, true), new XmlUrlResolver()); Log(Level.Verbose, "Using {0} to process '{1}' to '{2}'.", xslEngineName, srcInfo.FullName, destInfo.FullName); xslt.Transform(xml, xsltArgs, writer); } finally { // restore original current directory Directory.SetCurrentDirectory(originalCurrentDirectory); } } catch (Exception ex) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1151"), srcInfo.FullName, XsltFile), Location, ex); } finally { // ensure file handles are closed if (xmlReader != null) { xmlReader.Close(); } if (xslReader != null) { xslReader.Close(); } if (writer != null) { writer.Close(); } } } } }