Update of /cvsroot/mvp-xml/nxslt/v2/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3472/v2/src Added Files: .cvsignore NXslt.ico NXsltArgumentsParser.cs NXsltOptions.cs NXsltStrings.Designer.cs NXsltStrings.resx NXsltTimings.cs NxsltCommandLineParsingException.cs NxsltException.cs NxsltMain.cs Reporter.cs TypeUtils.cs Utils.cs issues.txt nxslt.snk nxslt2.csproj nxslt2.sln readme.txt Log Message: --- NEW FILE: issues.txt --- 1. Move to regexp in xmlns parsing. 2. The same for parsing parameters. 3. No more partial assembly names. 4. Add XSLT settings to options (trusted/encoding). --- NEW FILE: nxslt.snk --- (This appears to be a binary file; contents omitted.) --- NEW FILE: Utils.cs --- using System; using System.Xml; using System.Text; using System.Net; using System.Text.RegularExpressions; using System.Xml.XPath; namespace XmlLab.nxslt { internal static class Utils { /// <summary> /// Pretty prints XML document using XmlWriter's formatting functionality. /// </summary> /// <param name="reader">Source XML reader</param> /// <param name="options">Parsed command line options</param> public static void PrettyPrint(XmlReader reader, NXsltOptions options) { XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.Indent = true; writerSettings.NewLineOnAttributes = true; writerSettings.Encoding = new UTF8Encoding(false); XmlWriter writer; if (options.OutFile != null) { //Pretty print to a file writer = XmlWriter.Create(options.OutFile, writerSettings); } else { //Pretty print to the console writer = XmlWriter.Create(Console.Out, writerSettings); } while (reader.ReadState != ReadState.EndOfFile) { writer.WriteNode(reader, false); } writer.Close(); reader.Close(); } /// <summary> /// Gets XmlResolver - default or custom, with user credentials or not. /// </summary> /// <param name="credentials">User credentials</param> /// <param name="options">Parsed command line options</param> public static XmlResolver GetXmlResolver(NetworkCredential credentials, NXsltOptions options) { XmlResolver resolver; Type resolverType; if (options.ResolverTypeName != null) { //Custom resolver try { resolverType = TypeUtils.FindType(options, options.ResolverTypeName); } catch (Exception e) { throw new NXsltException(NXsltStrings.ErrorCreateResolver, options.ResolverTypeName, e.Message); } if (!typeof(XmlResolver).IsAssignableFrom(resolverType)) { //Type is not XmlResolver throw new NXsltException(NXsltStrings.ErrorTypeNotXmlResolver, options.ResolverTypeName); } try { resolver = (XmlResolver)Activator.CreateInstance(resolverType); } catch (Exception e) { throw new NXsltException(NXsltStrings.ErrorCreateResolver, options.ResolverTypeName, e.Message); } } else { //Standard resolver resolver = new XmlUrlResolver(); } //Set credentials if any if (credentials != null) { resolver.Credentials = credentials; } return resolver; } public static string ExtractStylsheetHrefFromPI(XPathNavigator pi) { Regex r = new Regex(@"href[ \n\t\r]*=[ \n\t\r]*""(.*)""|href[ \n\t\r]*=[ \n\t\r]*'(.*)'"); Match m = r.Match(pi.Value); if (!m.Success) { //Absent href preudo attribute throw new NXsltException(NXsltStrings.ErrorInvalidPI); } //Found href pseudo attribute value string href = m.Groups[1].Success ? m.Groups[1].Value : m.Groups[2].Value; return href; } } } --- NEW FILE: Reporter.cs --- using System; using System.Reflection; using System.IO; using System.Xml; using System.Text; namespace XmlLab.nxslt { /// <summary> /// nxslt reporter class. /// </summary> internal class Reporter { private static TextWriter stdout = Console.Out; private static TextWriter stderr = Console.Error; /// <summary> /// Reports command line parsing error. /// </summary> /// <param name="msg">Error message</param> public static void ReportCommandLineParsingError(string msg) { ReportUsage(); stderr.WriteLine(NXsltStrings.ErrorCommandLineParsing); stderr.WriteLine(); stderr.WriteLine(msg); } /// <summary> /// Reports an error. /// </summary> /// <param name="msg">Error message</param> public static void ReportError(string msg) { stderr.WriteLine(); stderr.WriteLine(msg); stderr.WriteLine(); } /// <summary> /// Reports an error. /// </summary> /// <param name="msg">Error message</param> /// <param name="arg">Message argument</param> public static void ReportError(string msg, params string[] args) { stderr.WriteLine(); stderr.WriteLine(msg, args); stderr.WriteLine(); } /// <summary> /// Reports command line parsing error. /// </summary> /// <param name="msg">Error message</param> /// <param name="arg">Message argument</param> public static void ReportCommandLineParsingError(string msg, params string[] args) { ReportUsage(); stderr.WriteLine(NXsltStrings.ErrorCommandLineParsing); stderr.WriteLine(); stderr.WriteLine(msg, args); } /// <summary> /// Prints nxslt usage info. /// </summary> public static void ReportUsage() { Version ver = Assembly.GetExecutingAssembly().GetName().Version; stderr.WriteLine(NXsltStrings.UsageHeader, ver.Major, ver.Minor, ver.Build, System.Environment.Version.Major, System.Environment.Version.Minor, System.Environment.Version.Build, System.Environment.Version.Revision); stderr.WriteLine(); stderr.WriteLine(NXsltStrings.UsageBody); } /// <summary> /// Prints timing info. /// </summary> public static void ReportTimings(ref NXsltTimings timings) { Version ver = Assembly.GetExecutingAssembly().GetName().Version; stderr.WriteLine(NXsltStrings.UsageHeader, ver.Major, ver.Minor, ver.Build, System.Environment.Version.Major, System.Environment.Version.Minor, System.Environment.Version.Build, System.Environment.Version.Revision); stderr.WriteLine(); stderr.WriteLine(NXsltStrings.Timings, timings.XsltCompileTime, timings.XsltExecutionTime, timings.TotalRunTime); } /// <summary> /// Returns full exception's message (including inner exceptions); /// </summary> public static String GetFullMessage(Exception e) { Exception ex = e; StringBuilder msg = new StringBuilder(); while (ex != null) { if (ex is NXsltException) { msg.AppendFormat(ex.Message); } else { msg.AppendFormat("{0}: {1}", ex.GetType().FullName, ex.Message); } if (ex.InnerException != null) { msg.Append(" ---> "); } ex = ex.InnerException; } return msg.ToString(); } } } --- NEW FILE: .cvsignore --- bin obj *.user *.suo *.vspscc *.pdb *.dll --- NEW FILE: NxsltException.cs --- using System; namespace XmlLab.nxslt { /// <summary> /// General nxslt error. /// </summary> internal class NXsltException : Exception { public NXsltException(string msg) : base(msg) { } public NXsltException(string msg, string arg) : base(string.Format(msg, arg)) { } public NXsltException(string msg, params string[] args) : base(string.Format(msg, args)) { } } } --- NEW FILE: NXsltStrings.Designer.cs --- (This appears to be a binary file; contents omitted.) --- NEW FILE: NxsltMain.cs --- using System; using System.Xml.XPath; using System.Xml.Xsl; using System.Xml.Schema; using System.Xml; using System.IO; using System.Net; using System.Text; using System.Diagnostics; //using GotDotNet.Exslt; //using Mvp.Xml.XInclude; namespace XmlLab.nxslt { /// <summary> /// nxslt main class. /// </summary> public class NXsltMain { //Parsed command line options private NXsltOptions options; //nxslt return codes private const int RETURN_CODE_OK = 0; private const int RETURN_CODE_ERROR = -1; //Timings private NXsltTimings timings; /// <summary> /// nxslt main entry point. /// </summary> /// <param name="args">Command line args</param> public static int Main(string[] args) { try { NXsltMain nxslt = new NXsltMain(); NXsltArgumentsParser clParser = new NXsltArgumentsParser(); nxslt.options = clParser.ParseArguments(args); //Ok, then let's process it return nxslt.Process(); } catch (NXsltCommandLineParsingException clpe) { //There was an exception while parsing command line Reporter.ReportCommandLineParsingError(Reporter.GetFullMessage(clpe)); return RETURN_CODE_ERROR; } catch (NXsltException ne) { Reporter.ReportError(Reporter.GetFullMessage(ne)); return RETURN_CODE_ERROR; } catch (Exception e) { //Some other exception Reporter.ReportError(NXsltStrings.Error, Reporter.GetFullMessage(e)); return RETURN_CODE_ERROR; } }// Main() method /// <summary> /// Process command line arguments and applies the specified stylesheet /// to the specified source document. /// </summary> private int Process() { //Start timing if needed Stopwatch totalTimer = null; if (options.ShowTiming) { timings = new NXsltTimings(); totalTimer = new Stopwatch(); totalTimer.Start(); } //Just show help if (options.ShowHelp) { Reporter.ReportUsage(); return RETURN_CODE_OK; } //Check that everything is in place if (options.Source == null && !options.LoadSourceFromStdin && !options.NoSourceXml) { Reporter.ReportCommandLineParsingError(NXsltStrings.ErrorMissingSource); return RETURN_CODE_ERROR; } if (options.Stylesheet == null && !options.LoadStylesheetFromStdin && !options.GetStylesheetFromPI && !options.PrettyPrintMode) { //No stylesheet - run identity transform options.IdentityTransformMode = true; } if (options.PrettyPrintMode && (options.Stylesheet != null || options.LoadStylesheetFromStdin || options.GetStylesheetFromPI)) { Reporter.ReportCommandLineParsingError(NXsltStrings.ErrorStylesheetAndPrettyPrintMode); return RETURN_CODE_ERROR; } //Check supported features if (options.MultiOutput) { Reporter.ReportError("Multioutput support is not implemented yet."); return RETURN_CODE_ERROR; } if (options.ExsltLibPath != null) { Reporter.ReportError("EXSLT support is not implemented yet."); return RETURN_CODE_ERROR; } //Prepare source XML reader XmlReader srcReader = PrepareSourceReader(); if (options.PrettyPrintMode) { //Process in pretty-print mode Utils.PrettyPrint(srcReader, options); } else { //Process transformation XmlResolver stylesheetResolver = Utils.GetXmlResolver(options.XSLTCredential, options); if (options.GetStylesheetFromPI) { //To get stylesheet from the PI we load source XML into //XPathDocument (consider embedded stylesheet) XPathDocument srcDoc = new XPathDocument(srcReader); XPathNavigator srcNav = srcDoc.CreateNavigator(); //Now srcReader reads in-memory cache instead srcReader = srcNav.ReadSubtree(); XslCompiledTransform xslt = PrepareStylesheetFromPI(srcNav, stylesheetResolver); Transform(srcReader, xslt, stylesheetResolver); } else { XslCompiledTransform xslt = PrepareStylesheet(stylesheetResolver); Transform(srcReader, xslt, stylesheetResolver); } } if (options.ShowTiming) { totalTimer.Stop(); timings.TotalRunTime = totalTimer.ElapsedMilliseconds; Reporter.ReportTimings(ref timings); } return RETURN_CODE_OK; } /// <summary> /// Performs XSL Transformation. /// </summary> private void Transform(XmlReader srcReader, XslCompiledTransform xslt, XmlResolver resolver) { Stopwatch transformTimer = null; if (options.ShowTiming) { transformTimer = new Stopwatch(); transformTimer.Start(); } if (options.OutFile != null) { //Transform to a file FileStream fs; try { fs = File.OpenWrite(options.OutFile); } catch { throw new NXsltException(NXsltStrings.ErrorCreatingFile, options.OutFile); } try { XmlWriter results = XmlWriter.Create(fs, xslt.OutputSettings); TransformImpl(srcReader, xslt, resolver, results); } finally { fs.Close(); } } else { //Transform to Console XmlWriter results = XmlWriter.Create(Console.Out, xslt.OutputSettings); TransformImpl(srcReader, xslt, resolver, results); } //Save transfomation time if (options.ShowTiming) { transformTimer.Stop(); timings.XsltExecutionTime = transformTimer.ElapsedMilliseconds; } } /// <summary> /// Actual transformation and error handling. /// </summary> private void TransformImpl(XmlReader srcReader, XslCompiledTransform xslt, XmlResolver resolver, XmlWriter results) { try { xslt.Transform(srcReader, options.XslArgList, results, resolver); } catch (XmlException xe) { string uri = options.LoadSourceFromStdin ? NXsltStrings.FromStdin : xe.SourceUri; throw new NXsltException(NXsltStrings.ErrorParsingDoc, uri, Reporter.GetFullMessage(xe)); } catch (XmlSchemaValidationException ve) { string uri = options.LoadSourceFromStdin ? NXsltStrings.FromStdin : srcReader.BaseURI; throw new NXsltException(NXsltStrings.ErrorParsingDoc, uri, Reporter.GetFullMessage(ve)); } catch (Exception e) { throw new NXsltException(NXsltStrings.ErrorTransform, Reporter.GetFullMessage(e)); } } /// <summary> /// Prepares, loads and compiles XSLT stylesheet. /// </summary> private XslCompiledTransform PrepareStylesheet(XmlResolver stylesheetResolver) { Stopwatch xsltCompileTimer = null; if (options.ShowTiming) { xsltCompileTimer = new Stopwatch(); xsltCompileTimer.Start(); } XmlReader stylesheetReader = PrepareStylesheetReader(stylesheetResolver); XslCompiledTransform xslt = CreateTransform(stylesheetResolver, stylesheetReader); //Save stylesheet loading/compilation time if (options.ShowTiming) { xsltCompileTimer.Stop(); timings.XsltCompileTime = xsltCompileTimer.ElapsedMilliseconds; } return xslt; } /// <summary> /// Creates XslCompiledTransform instance for given reader and resolver. /// </summary> private XslCompiledTransform CreateTransform(XmlResolver stylesheetResolver, XmlReader stylesheetReader) { XslCompiledTransform xslt = new XslCompiledTransform(); try { xslt.Load(stylesheetReader, XsltSettings.TrustedXslt, stylesheetResolver); } catch (XmlException xe) { string uri = options.LoadStylesheetFromStdin ? NXsltStrings.FromStdin : xe.SourceUri; throw new NXsltException(NXsltStrings.ErrorParsingDoc, uri, Reporter.GetFullMessage(xe)); } catch (Exception e) { string uri = options.LoadStylesheetFromStdin ? NXsltStrings.FromStdin : stylesheetReader.BaseURI; throw new NXsltException(NXsltStrings.ErrorCompileStyle, uri, Reporter.GetFullMessage(e)); } return xslt; } /// <summary> /// Prepares, loads and compiles XSLT stylesheet referenced in the PI. /// </summary> private XslCompiledTransform PrepareStylesheetFromPI(XPathNavigator srcNav, XmlResolver stylesheetResolver) { Stopwatch xsltCompileTimer = null; if (options.ShowTiming) { xsltCompileTimer = new Stopwatch(); xsltCompileTimer.Start(); } XPathNavigator pi = srcNav.SelectSingleNode("/processing-instruction('xml-stylesheet')"); if (pi == null) { //Absent xml-stylesheet PI throw new NXsltException(NXsltStrings.ErrorInvalidPI); } //Found PI node, look for the href pseudo attribute string href = Utils.ExtractStylsheetHrefFromPI(pi); XslCompiledTransform xslt = null; if (href.StartsWith("#")) { //Embedded stylesheet string id = href.Remove(0, 1); XPathNavigator embStylesheet = srcNav.SelectSingleNode("id('" + id + "')|/descendant::*[@id='" + id + "']"); if (embStylesheet == null) { //Unresolvable stylesheet URI throw new NXsltException(NXsltStrings.ErrorPIStylesheetNotFound, href); } xslt = CreateTransform(stylesheetResolver, embStylesheet.ReadSubtree()); } else { //External stylesheet options.Stylesheet = href; xslt = PrepareStylesheet(stylesheetResolver); } //Save stylesheet loading/compilation time if (options.ShowTiming) { xsltCompileTimer.Stop(); timings.XsltCompileTime = xsltCompileTimer.ElapsedMilliseconds; } return xslt; } /// <summary> /// Prepares source XML reader. /// </summary> /// <returns>XmlReader over source XML</returns> private XmlReader PrepareSourceReader() { XmlReaderSettings srcReaderSettings = new XmlReaderSettings(); srcReaderSettings.ProhibitDtd = false; if (options.StripWhiteSpace || options.PrettyPrintMode) { srcReaderSettings.IgnoreWhitespace = true; } if (options.ValidateDocs) { srcReaderSettings.ValidationType = ValidationType.DTD; } if (!options.ResolveExternals) srcReaderSettings.XmlResolver = null; else { XmlResolver srcResolver = Utils.GetXmlResolver(options.SourceCredential, options); } XmlReader srcReader; if (options.NoSourceXml) { //No source XML - create dummy one srcReader = XmlReader.Create(new StringReader("<dummy/>"), srcReaderSettings); } else if (options.LoadSourceFromStdin) { //Get source from stdin srcReader = XmlReader.Create(Console.OpenStandardInput(), srcReaderSettings); } else { //Get source from URI srcReader = XmlReader.Create(options.Source, srcReaderSettings); } //Chain schema validaring reader on top if (options.ValidateDocs) { srcReaderSettings.ValidationType = ValidationType.Schema; srcReaderSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; return XmlReader.Create(srcReader, srcReaderSettings); } return srcReader; } /// <summary> /// Prepares stylesheet XML reader. /// </summary> /// <returns>XmlReader over source XML</returns> private XmlReader PrepareStylesheetReader(XmlResolver stylesheetResolver) { XmlReaderSettings stylesheetReaderSettings = new XmlReaderSettings(); stylesheetReaderSettings.ProhibitDtd = false; if (options.ValidateDocs) { stylesheetReaderSettings.ValidationType = ValidationType.DTD; } if (options.StripWhiteSpace) { stylesheetReaderSettings.IgnoreWhitespace = true; } if (!options.ResolveExternals) stylesheetReaderSettings.XmlResolver = null; else { stylesheetReaderSettings.XmlResolver = stylesheetResolver; } XmlReader stylesheetReader; if (options.IdentityTransformMode) { //No XSLT - use identity transformation stylesheetReader = XmlReader.Create(new StringReader(NXsltStrings.IdentityTransformation), stylesheetReaderSettings); } else if (options.LoadStylesheetFromStdin) { //Get stylesheet from stdin stylesheetReader = XmlReader.Create(Console.OpenStandardInput(), stylesheetReaderSettings); } else { //Get source from URI stylesheetReader = XmlReader.Create(options.Stylesheet, stylesheetReaderSettings); } //Chain schema validaring reader on top if (options.ValidateDocs) { stylesheetReaderSettings.ValidationType = ValidationType.Schema; stylesheetReaderSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; return XmlReader.Create(stylesheetReader, stylesheetReaderSettings); } return stylesheetReader; } }// NXsltMain class }// XmlLab.nxslt namespace --- NEW FILE: nxslt2.sln --- (This appears to be a binary file; contents omitted.) --- NEW FILE: NXsltStrings.resx --- <?xml version="1.0" encoding="utf-8"?> <root> <!-- Microsoft ResX Schema Version 2.0 The primary goals of this format is to allow a simple XML format that is mostly human readable. The generation and parsing of the various data types are done through the TypeConverter classes associated with the data types. Example: ... ado.net/XML headers & schema ... <resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="version">2.0</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <value>[base64 mime encoded serialized .NET Framework object]</value> </data> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <comment>This is a comment</comment> </data> There are any number of "resheader" rows that contain simple name/value pairs. Each data row contains a name, and value. The row also contains a type or mimetype. Type corresponds to a .NET class that support text/value conversion through the TypeConverter architecture. Classes that don't support this are serialized and stored with the mimetype set. The mimetype is used for serialized objects, and tells the ResXResourceReader how to depersist the object. This is currently not extensible. For a given mimetype the value must be set accordingly: Note - application/x-microsoft.net.object.binary.base64 is the format that the ResXResourceWriter will generate, however the reader can read any of the formats listed below. mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Soap.SoapFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.bytearray.base64 value : The object must be serialized into a byte array : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="UsageHeader"> <value xml:space="preserve">.NET XSLT command line utility, version {0}.{1} Beta1 build {2} (c) 2004 Oleg Tkachenko, http://www.xmllab.net Running under .NET {3}.{4}.{5}.{6}</value> </data> <data name="UsageBody"> <value xml:space="preserve">Usage: nxslt source stylesheet [options] [param=value...] [xmlns:prefix=uri...] Options: -? Show this message -o filename Write output to named file -xw Strip non-significant whitespace from source and stylesheet -xe Do not resolve external definitions during parse phase -xi Do not process XInclude during parse phase -v Validate documents during parse phase -t Show load and transformation timings -xs No source XML -pp Pretty-print source document -pi Get stylesheet URL from xml-stylesheet PI in source document -r Use named URI resolver class -af Assembly file name to look up URI resolver class -an Assembly full or partial name to look up URI resolver class -mo Allow multiple output documents -ext Comma-separated list of extension object class names -exslt Use specified EXSLT.NET assembly instead of built-in implementation (#GAC to load the assembly from the GAC) -xmlc creds Credentials in username:password@domain format to be used in Web request authentications when loading source XML -xslc creds Credentials in username:password@domain format to be used in Web request authentications when loading XSLT - Dash used as source argument loads XML from stdin - Dash used as stylesheet argument loads XSL from stdin </value> </data> <data name="ErrorCommandLineParsing"> <value xml:space="preserve">An error occurred while parsing command line.</value> </data> <data name="ErrorMissingSource"> <value xml:space="preserve">Missing source filename.</value> </data> <data name="ErrorMissingStylesheet"> <value xml:space="preserve">Missing stylesheet filename.</value> </data> <data name="ErrorParsingDoc"> <value xml:space="preserve">An error occurred while parsing document: {0}: {1}</value> </data> <data name="ErrorMissingOutFileName"> <value xml:space="preserve">Missing output filename after '-o' option.</value> </data> <data name="ErrorCreatingFile"> <value xml:space="preserve">An error occurred while creating file '{0}'.</value> </data> <data name="ErrorUnboundedPrefix"> <value xml:space="preserve">Prefix '{0}' cannot be resolved. Use xmlns:{0}='...' to bind '{0}' to a URI.</value> </data> <data name="ErrorWrongParam"> <value xml:space="preserve">Parameter name '{0}' must be followed by an '=' character.</value> </data> <data name="ErrorBothStdin"> <value xml:space="preserve">The input and the stylesheet document cannot both be read from stdin. At least one of them must be loaded from a URL.</value> </data> <data name="ErrorUnrecognizedOption"> <value xml:space="preserve">Unrecognized option : '{0}'.</value> </data> <data name="FromStdin"> <value xml:space="preserve"><from stdin></value> </data> <data name="ErrorInvalidPI"> <value xml:space="preserve">The source document does not contain an 'xml-stylesheet' processing instruction of this form: <?xml-stylesheet type='text/xsl' href='stylesheet-url'?></value> </data> <data name="ErrorBothStylesheetAndPI"> <value xml:space="preserve">The '-pi' option cannot be used when the stylesheet argument is specified.</value> </data> <data name="ErrorBothNoSourceAndPI"> <value xml:space="preserve">The '-pi' and '-xs' options are mutually exclusive.</value> </data> <data name="ErrorBothNoSourceAndSource"> <value xml:space="preserve">The '-xs' option and source document filename (or '-') are mutually exclusive.</value> </data> <data name="Timings"> <value xml:space="preserve">Stylesheet load/compile time: {0, 9:f3} milliseconds Transformation time: {1, 9:f3} milliseconds Total execution time: {2, 9:f3} milliseconds </value> </data> <data name="ErrorTransform"> <value xml:space="preserve">An error occurred while executing transformation: {0}</value> </data> <data name="ErrorMissingName"> <value xml:space="preserve">The '=' character must be preceded by the name of a parameter or a namespace declaration.</value> </data> <data name="ErrorMissingValue"> <value xml:space="preserve">Parameter '{0}' is missing a value following the '=' character.</value> </data> <data name="ErrorMissingURI"> <value xml:space="preserve">Namespace declaration '{0}' is missing a URI following the '=' character.</value> </data> <data name="ErrorCompileStyle"> <value xml:space="preserve">An error occurred while compiling stylesheet '{0}': {1}</value> </data> <data name="ErrorPIStylesheetNotFound"> <value xml:space="preserve">Stylesheet '{0}', defined in 'xml-stylesheet' processing instruction not found.</value> </data> <data name="ErrorMissingResolverTypeName"> <value xml:space="preserve">Missing URI resolver type name after '-r' option.</value> </data> <data name="ErrorMissingAssemblyFileName"> <value xml:space="preserve">Missing assembly file name after '-af' option.</value> </data> <data name="ErrorMissingExtClassNames"> <value xml:space="preserve">Missing list of extension class names after '-ext' option.</value> </data> <data name="ErrorMissingAssemblyName"> <value xml:space="preserve">Missing assembly name after '-an' option.</value> </data> <data name="ErrorLoadAssembly"> <value xml:space="preserve">An error occurred while loading assembly '{0}'.</value> </data> <data name="ErrorGetTypeFromAssembly"> <value xml:space="preserve">Type '{0}' not found in '{1}' assembly.</value> </data> <data name="ErrorCreateResolver"> <value xml:space="preserve">An error occurred while instantiating '{0}' type: {1}</value> </data> <data name="ErrorTypeNotXmlResolver"> <value xml:space="preserve">Specified URI resolver type '{0}' is not XmlResolver type.</value> </data> <data name="ErrorGetType"> <value xml:space="preserve">Type '{0}' not found.</value> </data> <data name="ErrorBothAssemblyFileNameAndName"> <value xml:space="preserve">-af and -an options cannot be used simultaneously.</value> </data> <data name="ErrorExtNamespaceClash"> <value xml:space="preserve">Two extension objects cannot be bound to '{0}' namespace URI.</value> </data> <data name="ErrorExtNoNamespace"> <value xml:space="preserve">Extension object '{0}' must be bound to a namespace URI.</value> </data> <data name="ErrorMissingExsltLibPath"> <value xml:space="preserve">Missing EXSLT.NET assembly file path after '-exslt' option.</value> </data> <data name="ErrorLoadExsltLibNotFound"> <value xml:space="preserve">An error occurred while loading specified EXSLT.NET assembly '{0}'. Error details: {1}</value> </data> <data name="ErrorLoadExsltTransformTypeNotFound"> <value xml:space="preserve">Specified EXSLT.NET assembly '{0}' doesn't contain GotDotNet.Exslt.ExsltTransform class. Error details: {1}</value> </data> <data name="ErrorLoadExsltTransformTypeCannotBeInstantiated"> <value xml:space="preserve">GotDotNet.Exslt.ExsltTransform class from specified EXSLT.NET assembly '{0}' cannot be instantiated. Error details: {1}</value> </data> <data name="ErrorMissingXMLCredentials"> <value xml:space="preserve">Missing credentials after '-xmlc' option.</value> </data> <data name="ErrorMissingXSLTCredentials"> <value xml:space="preserve">Missing credentials after '-xslc' option.</value> </data> <data name="PatternCredentials"> <value xml:space="preserve">(?<username>\w+):?(?<psw>\w*)@?(?<domain>\w*)</value> </data> <data name="ErrorBadCredentials"> <value xml:space="preserve">Specified credentials '{0}' don't match username:password@domain pattern.</value> </data> <data name="ErrorDuplicateCredentials"> <value xml:space="preserve">Duplicate credentials.</value> </data> <data name="ErrorStylesheetAndPrettyPrintMode"> <value xml:space="preserve">No stylesheet (in file name, '-' or '-pi' ways) should be specified along with '-pp' option.</value> </data> <data name="IdentityTransformation"> <value xml:space="preserve"><xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <xsl:copy-of select="."/> </xsl:template> </xsl:transform></value> </data> <data name="Error"> <value xml:space="preserve">An error occured: {0}</value> </data> </root> --- NEW FILE: NXsltArgumentsParser.cs --- using System; using System.Resources; using System.Xml; using System.Collections.Generic; using System.Xml.Xsl; using System.Net; using System.Text.RegularExpressions; namespace XmlLab.nxslt { /// <summary> /// Command line arguments parser. /// </summary> internal class NXsltArgumentsParser { private XmlNamespaceManager namespaceManager = null; private Queue<string> paramQueue = null; private NameTable nameTable = null; /// <summary> /// Parses command line arguments into NXsltOptions collection. /// </summary> /// <param name="args">Command line arguments.</param> /// <returns>Parsed collection of options.</returns> public NXsltOptions ParseArguments(string[] args) { NXsltOptions options = new NXsltOptions(); for (int i = 0; i < args.Length; i++) { string arg = args[i]; switch (arg) { //Show help case "-?": options.ShowHelp = true; break; //Strip whitespace case "-xw": options.StripWhiteSpace = true; break; //Output filename case "-o": if (i == args.Length - 1) { //Absent file name throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingOutFileName); } else { //Next argument must be filename options.OutFile = args[++i]; break; } case "-exslt": if (i == args.Length - 1) { //Absent exslt lib path throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingExsltLibPath); } else { //Next argument must be lib path options.ExsltLibPath = args[++i]; break; } //Show timings case "-t": options.ShowTiming = true; break; //No source XML case "-xs": if (options.GetStylesheetFromPI) { //Both -xs and -pi cannot be specified throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothNoSourceAndPI); } else if ((options.Source != null && options.Stylesheet != null) || options.LoadSourceFromStdin) { //When using -xs no source shoold be specified throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothNoSourceAndSource); } else if (options.Source != null && options.Stylesheet == null) { //That was stylesheet, not source options.Stylesheet = options.Source; options.Source = null; } options.NoSourceXml = true; break; //Get stylesheet URI from xml-stylesheet PI case "-pi": if (options.Stylesheet != null || options.LoadStylesheetFromStdin) { //Both -pi and stylesheet cannot be specified throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothStylesheetAndPI); } else if (options.NoSourceXml) { //Both -xs and -pi cannot be specified throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothNoSourceAndPI); } else options.GetStylesheetFromPI = true; break; //Network credentials for source XML case "-xmlc": if (i == args.Length - 1) { //Absent credentials throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingXMLCredentials); } else { //Next argument must be credentials string credstring = args[++i]; if (options.SourceCredential != null) { //Duplicate credentials throw new NXsltCommandLineParsingException(NXsltStrings.ErrorDuplicateCredentials); } options.SourceCredential = ParseCredentials(credstring); break; } //Network credentials for stylesheet case "-xslc": if (i == args.Length - 1) { //Absent credentials throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingXSLTCredentials); } else { //Next argument must be credentials string credstring = args[++i]; if (options.XSLTCredential != null) { //Duplicate credentials throw new NXsltCommandLineParsingException(NXsltStrings.ErrorDuplicateCredentials); } options.XSLTCredential = ParseCredentials(credstring); break; } //Use named URI resolver type case "-r": if (i == args.Length - 1) { //Absent resolver type name throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingResolverTypeName); } else { //Next argument must be resolver type options.ResolverTypeName = args[++i]; break; } //Assembly file name case "-af": if (options.AssemblyName != null) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothAssemblyFileNameAndName); } if (i == args.Length - 1) { //Absent assembly file name throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingAssemblyFileName); } else { //Next argument must be assembly file name options.AssemblyFileName = args[++i]; break; } //Assembly name case "-an": if (options.AssemblyFileName != null) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothAssemblyFileNameAndName); } if (i == args.Length - 1) { //Absent assembly name throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingAssemblyName); } else { //Next argument must be assembly name options.AssemblyName = args[++i]; break; } //Allow multiple output documents case "-mo": options.MultiOutput = true; break; //Validate documents case "-v": options.ValidateDocs = true; break; //Do not resolve externals case "-xe": options.ResolveExternals = false; break; //Do not process XInclude case "-xi": options.ProcessXInclude = false; break; //Pretty print source XML case "-pp": options.PrettyPrintMode = true; break; //Extension class names case "-ext": if (i == args.Length - 1) { //Absent class names throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingExtClassNames); } else { //Next argument must be ext class names list options.ExtClasses = args[++i].Split(','); break; } //Source or Stylesheet to be read from stdin case "-": if (options.Source == null && !options.LoadSourceFromStdin) { options.LoadSourceFromStdin = true; } else if (options.Stylesheet == null && !options.LoadStylesheetFromStdin) { //Check out that both source and stylesheet are not "-" if (options.LoadSourceFromStdin) { //Both source and stylesheet cannot be read from stdin throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBothStdin); } else options.LoadStylesheetFromStdin = true; } else { //Unrecognized "-" throw new NXsltCommandLineParsingException(NXsltStrings.ErrorUnrecognizedOption, arg); } break; //Other argment - source URI, stylesheet URI, parameter or namespace declaration default: //namespace declaration? if ((arg.StartsWith("xmlns:") || arg.StartsWith("xmlns=")) && arg.Contains("=")) { ParseNamespaceDeclaration(arg); } //Parameter? else if (arg.Contains("=")) { //Parameter - put to the queue till all namespaces are not processed if (arg.StartsWith("=")) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingName); } else if (arg.EndsWith("=")) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingValue, arg.Remove(arg.Length - 1, 1)); } //Enqueue param till all namespace declarations parsed EnqueueParameter(args, arg, paramQueue); } else if (arg.StartsWith("-")) { //Unrecognized option throw new NXsltCommandLineParsingException(NXsltStrings.ErrorUnrecognizedOption, arg); } //Source URI? else if (options.Source == null && !options.LoadSourceFromStdin && !options.NoSourceXml) { options.Source = arg; } //Stylesheet URI? else if (options.Stylesheet == null && !options.LoadStylesheetFromStdin && !options.GetStylesheetFromPI) { options.Stylesheet = arg; } //Unrecognized argument else { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorUnrecognizedOption, arg); } break; } } //Resolve parameters ResolveParameters(options); //Instantiate specified extension objects ParseExtObjects(options); return options; } /// <summary> /// Saves param in a queue. /// </summary> /// <param name="args">Command line arguments</param> /// <param name="param">Parameter</param> /// <param name="paramQueue">Queue of paramerers</param> private void EnqueueParameter(string[] args, string param, Queue<string> paramQueue) { //Lazy param queue if (paramQueue == null) { //Creates queue with max capacity = max possible number of params paramQueue = new Queue<string>(args.Length - 2); } paramQueue.Enqueue(param); } // ParseArguments /// <summary> /// Auxilary method for parsing credentials /// </summary> /// <param name="value">Passed credentials in username:password@domain form</param> private NetworkCredential ParseCredentials(string value) { NetworkCredential creds = new NetworkCredential(); Regex r = new Regex(NXsltStrings.PatternCredentials); Match m = r.Match(value); if (!m.Success) { //Credentials doesn't match pattern throw new NXsltCommandLineParsingException(NXsltStrings.ErrorBadCredentials, value); } creds.UserName = m.Groups["username"].Value; if (m.Groups["psw"] != null) creds.Password = m.Groups["psw"].Value; if (m.Groups["domain"] != null) creds.Domain = m.Groups["domain"].Value; return creds; } //SetCredentials /// <summary> /// Parses XML namespace declaration. /// </summary> /// <param name="arg">Namespace declaration</param> private void ParseNamespaceDeclaration(string arg) { if (arg.EndsWith("=")) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorMissingURI, arg.Remove(arg.Length - 1, 1)); } int eqIndex = arg.IndexOf('='); //Lazy XmlNamespaceManager if (namespaceManager == null) { nameTable = new NameTable(); namespaceManager = new XmlNamespaceManager(nameTable); } //qname is xmlns:prefix or xmlns string qname = arg.Substring(0, eqIndex); int colonIndex = qname.IndexOf(':'); if (colonIndex != -1) //xmlns:prefix="value" case namespaceManager.AddNamespace(nameTable.Add(qname.Substring(colonIndex + 1)), arg.Substring(eqIndex + 1)); else //xmlns="value" case - default namespace namespaceManager.AddNamespace(String.Empty, arg.Substring(eqIndex + 1)); }// ParseNamespaceDeclaration /// <summary> /// Resolves enqueued parameters. /// </summary> /// <param name="options">nxslt options collection</param> private void ResolveParameters(NXsltOptions options) { if (paramQueue != null) { options.XslArgList = new XsltArgumentList(); foreach (string param in paramQueue) { int eqIndex = param.IndexOf('='); //qname is prefix:localname or localname string qname = param.Substring(0, eqIndex); int colonIndex = qname.IndexOf(':'); if (colonIndex != -1) { //prefix:localname="value" case string prefix = qname.Substring(0, colonIndex); string uri; //Resolve prefix if (namespaceManager == null || (uri = namespaceManager.LookupNamespace(nameTable.Get(prefix))) == null) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorUnboundedPrefix, prefix); } else options.XslArgList.AddParam(param.Substring(colonIndex + 1, eqIndex - colonIndex - 1), uri, param.Substring(eqIndex + 1)); } else //localname="value" case - possible default namespace options.XslArgList.AddParam(qname, namespaceManager == null ? String.Empty : namespaceManager.DefaultNamespace, param.Substring(eqIndex + 1)); } } }// ResolveParameters /// <summary> /// Parses and instantiates extention objects. /// </summary> /// <param name="options">nxslt options collection</param> private void ParseExtObjects(NXsltOptions options) { if (options.ExtClasses != null) { if (options.XslArgList == null) options.XslArgList = new XsltArgumentList(); foreach (string typeDecl in options.ExtClasses) { string[] parts = typeDecl.Split(new char[] { ':' }, 2); if (parts.Length == 1) { Type extObjType = TypeUtils.FindType(options, parts[0]); try { object o = Activator.CreateInstance(extObjType); if (namespaceManager == null || namespaceManager.DefaultNamespace == String.Empty) { //Extension object not bound to a namespace throw new NXsltException(NXsltStrings.ErrorExtNoNamespace, parts[0]); } string ns = namespaceManager.DefaultNamespace; if (options.XslArgList.GetExtensionObject(ns) != null) { //More than one extension object in the same namespace URI throw new NXsltException(NXsltStrings.ErrorExtNamespaceClash, ns); } options.XslArgList.AddExtensionObject(ns, o); } catch (Exception e) { //Type cannot be instantiated throw new NXsltException(NXsltStrings.ErrorCreateResolver, parts[0], e.Message); } } else { string prefix = parts[0]; string uri; //Resolve prefix if (namespaceManager == null || (uri = namespaceManager.LookupNamespace(nameTable.Get(prefix))) == null) { throw new NXsltCommandLineParsingException(NXsltStrings.ErrorUnboundedPrefix, prefix); } Type extObjType = TypeUtils.FindType(options, parts[1]); try { object o = Activator.CreateInstance(extObjType); if (options.XslArgList.GetExtensionObject(uri) != null) { //More than one extension object in the same namespace URI throw new NXsltCommandLineParsingException(NXsltStrings.ErrorExtNamespaceClash, uri); } options.XslArgList.AddExtensionObject(uri, o); } catch (Exception e) { //Type cannot be instantiated throw new NXsltCommandLineParsingException(NXsltStrings.ErrorCreateResolver, parts[1], e.Message); } } } } }// ParseExtObjects } // NXsltArgumentsParser } // XmlLab.nxslt namespace --- NEW FILE: NXslt.ico --- (This appears to be a binary file; contents omitted.) --- NEW FILE: TypeUtils.cs --- using System; using System.Reflection; namespace XmlLab.nxslt { /// <summary> /// Type utility methods. /// </summary> internal class TypeUtils { public static Type FindType(NXsltOptions options, string typeName) { Type type; Assembly assembly; if (options.AssemblyFileName != null) { // //Load assembly from a file // try { assembly = Assembly.LoadFrom(options.AssemblyFileName); } catch { //Assembly cannot be loaded throw new NXsltException(NXsltStrings.ErrorLoadAssembly, options.AssemblyFileName); } try { type = assembly.GetType(typeName, true); } catch { //Type not found in the specified assembly throw new NXsltException(NXsltStrings.ErrorGetTypeFromAssembly, typeName, options.AssemblyFileName); } } else if (options.AssemblyName != null) { // //Load assembly by name // try { //assembly = Assembly.LoadWithPartialName(options.AssemblyName); assembly = Assembly.Load(options.AssemblyName); } catch { //Assembly cannot be loaded throw new NXsltException(NXsltStrings.ErrorLoadAssembly, options.AssemblyName); } try { type = assembly.GetType(typeName, true); } catch { throw new NXsltException(NXsltStrings.ErrorGetType, typeName); } } else { // //Assembly not specified // try { type = Type.GetType(typeName, true); } catch { throw new NXsltException(NXsltStrings.ErrorGetType, typeName); } } return type; } // FindType() } } --- NEW FILE: nxslt2.csproj --- (This appears to be a binary file; contents omitted.) --- NEW FILE: NxsltCommandLineParsingException.cs --- using System; namespace XmlLab.nxslt { /// <summary> /// nxslt command line parsing error. /// </summary> internal class NXsltCommandLineParsingException : NXsltException { public NXsltCommandLineParsingException(string msg) : base(msg) { } public NXsltCommandLineParsingException(string msg, string arg) : base(string.Format(msg, arg)) { } public NXsltCommandLineParsingException(string msg, params string[] args) : base(string.Format(msg, args)) { } } } --- NEW FILE: NXsltTimings.cs --- using System; using System.Collections.Generic; using System.Text; namespace XmlLab.nxslt { internal struct NXsltTimings { public float XsltCompileTime; public float XsltExecutionTime; public float TotalRunTime; } } --- NEW FILE: readme.txt --- See http://www.xmllab.net for documentation. --- NEW FILE: NXsltOptions.cs --- using System; using System.Xml.Xsl; using System.Net; namespace XmlLab.nxslt { /// <summary> /// This class represents parsed command line options. /// </summary> internal class NXsltOptions { private bool stripWhiteSpace = false; private bool showHelp = false; private string source; private string stylesheet; private string outFile; private XsltArgumentList xslArgList; private bool showTiming = false; private bool getStylesheetFormPI = false; private bool validateDocs = false; private bool resolveExternals = true; private bool processXInclude = true; private bool loadSourceFromStdin = false; private bool loadStylesheetFromStdin = false; private string resolverTypeNam... [truncated message content] |