Update of /cvsroot/mvp-xml/EXSLT/v1/src/Exslt In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29285/v1/src/Exslt Added Files: .cvsignore AssemblyInfo.cs Exslt.csproj Exslt.csproj.user Exslt.csproj.vspscc ExsltCommon.cs ExsltContext.cs ExsltContextFunction.cs ExsltDatesAndTimes.cs ExsltMath.cs ExsltNamespaces.cs ExsltNodeList.cs ExsltRandom.cs ExsltRegularExpressions.cs ExsltSets.cs ExsltStrings.cs ExsltTransform.cs GDNDatesAndTimes.cs GDNDynamic.cs GDNMath.cs GDNRegularExpressions.cs GDNSets.cs GDNStrings.cs Makefile MethodRenamer.exe MethodRenamer.exe.config Mvp.Xml.Exslt.dll PostBuildEvent.bat ReadMe.htm index.html install.cmd uninstall.cmd Log Message: --- NEW FILE: ExsltNamespaces.cs --- namespace Mvp.Xml.Exslt { /// <summary> /// Exslt (and other) namespaces constants. /// </summary> public class ExsltNamespaces { public const string Common = "http://exslt.org/common"; public const string DatesAndTimes = "http://exslt.org/dates-and-times"; public const string Math = "http://exslt.org/math"; public const string Random = "http://exslt.org/random"; public const string RegularExpressions = "http://exslt.org/regular-expressions"; public const string Sets = "http://exslt.org/sets"; public const string Strings = "http://exslt.org/strings"; public const string GDNDatesAndTimes = "http://gotdotnet.com/exslt/dates-and-times"; public const string GDNMath = "http://gotdotnet.com/exslt/math"; public const string GDNRegularExpressions = "http://gotdotnet.com/exslt/regular-expressions"; public const string GDNSets = "http://gotdotnet.com/exslt/sets"; public const string GDNStrings = "http://gotdotnet.com/exslt/strings"; public const string GDNDynamic = "http://gotdotnet.com/exslt/dynamic"; } } --- NEW FILE: uninstall.cmd --- gacutil /u Mvp.Xml.Exslt --- NEW FILE: GDNStrings.cs --- namespace Mvp.Xml.Exslt { /// <summary> /// This class implements additional functions in the http://gotdotnet.com/exslt/strings namespace. /// </summary> public class GDNStrings { /// <summary> /// Implements the following function /// string uppercase(string) /// </summary> /// <param name="str"></param> /// <returns></returns> /// <remarks>THIS FUNCTION IS NOT IN EXSLT!!!</remarks> public string uppercase(string str) { return str.ToUpper(); } /// <summary> /// Implements the following function /// string lowercase(string) /// </summary> /// <param name="str"></param> /// <returns></returns> /// <remarks>THIS FUNCTION IS NOT IN EXSLT!!!</remarks> public string lowercase(string str) { return str.ToLower(); } } } --- NEW FILE: ExsltMath.cs --- #region using using System; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements the EXSLT functions in the http://exslt.org/math namespace. /// </summary> public class ExsltMath { /// <summary> /// Implements the following function /// number min(node-set) /// </summary> /// <param name="iterator"></param> /// <returns></returns> public double min(XPathNodeIterator iterator){ double min, t; if(iterator.Count == 0){ return Double.NaN; } try{ iterator.MoveNext(); min = XmlConvert.ToDouble(iterator.Current.Value); while(iterator.MoveNext()){ t = XmlConvert.ToDouble(iterator.Current.Value); min = (t < min)? t : min; } }catch(Exception){ return Double.NaN; } return min; } /// <summary> /// Implements the following function /// number max(node-set) /// </summary> /// <param name="iterator"></param> /// <returns></returns> public double max(XPathNodeIterator iterator){ double max, t; if(iterator.Count == 0){ return Double.NaN; } try{ iterator.MoveNext(); max = XmlConvert.ToDouble(iterator.Current.Value); while(iterator.MoveNext()){ t = XmlConvert.ToDouble(iterator.Current.Value); max = (t > max)? t : max; } }catch(Exception){ return Double.NaN; } return max; } /// <summary> /// Implements the following function /// node-set highest(node-set) /// </summary> /// <param name="iterator">The input nodeset</param> /// <returns>All the nodes that contain the max value in the nodeset</returns> public XPathNodeIterator highest(XPathNodeIterator iterator){ ExsltNodeList newList = new ExsltNodeList(); double max, t; if(iterator.Count == 0){ return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } try{ iterator.MoveNext(); max = XmlConvert.ToDouble(iterator.Current.Value); newList.Add(iterator.Current.Clone()); while (iterator.MoveNext()){ t = XmlConvert.ToDouble(iterator.Current.Value); if(t > max){ max = t; newList.Clear(); newList.Add(iterator.Current.Clone()); }else if( t == max){ newList.Add(iterator.Current.Clone()); } } }catch(Exception){ //return empty node set newList.Clear(); return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } /// <summary> /// Implements the following function /// node-set lowest(node-set) /// </summary> /// <param name="iterator">The input nodeset</param> /// <returns>All the nodes that contain the min value in the nodeset</returns> public XPathNodeIterator lowest(XPathNodeIterator iterator){ ExsltNodeList newList = new ExsltNodeList(); double min, t; if(iterator.Count == 0){ return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } try{ iterator.MoveNext(); min = XmlConvert.ToDouble(iterator.Current.Value); newList.Add(iterator.Current.Clone()); while (iterator.MoveNext()){ t = XmlConvert.ToDouble(iterator.Current.Value); if(t < min){ min = t; newList.Clear(); newList.Add(iterator.Current.Clone()); }else if( t == min){ newList.Add(iterator.Current.Clone()); } } }catch(Exception){ //return empty node set newList.Clear(); return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } return ExsltCommon.ExsltNodeListToXPathNodeIterator(newList); } /// <summary> /// Implements the following function /// number abs(number) /// </summary> /// <param name="number"></param> /// <returns></returns> public double abs(double number){ return Math.Abs(number); } /// <summary> /// Implements the following function /// number sqrt(number) /// </summary> /// <param name="number"></param> /// <returns></returns> public double sqrt(double number){ if (number < 0) return 0; return Math.Sqrt(number); } /// <summary> /// Implements the following function /// number power(number, number) /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double power(double x, double y){ return Math.Pow(x, y); } /// <summary> /// Implements the following function /// number log(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double log(double x){ return Math.Log(x); } /// <summary> /// Implements the following function /// number constant(string, number) /// </summary> /// <param name="number"></param> /// <returns>The specified constant or NaN</returns> /// <remarks>This method only supports the constants /// E and PI. Also the precision parameter is ignored.</remarks> public double constant(string c, double precision){ switch(c.ToUpper()) { case "E": return Math.E; case "PI": return Math.PI; case "SQRRT2" : return Math.Sqrt(2); case "LN2" : return Math.Log(2); case "LN10" : return Math.Log(10); case "LOG2E" : return Math.Log(Math.E, 2); case "SQRT1_2" : return Math.Sqrt(.5); default: return Double.NaN; } } /// <summary> /// Implements the following function /// number random() /// </summary> /// <param name="x"></param> /// <returns></returns> public double random(){ Random rand = new Random((int) DateTime.Now.Ticks); return rand.NextDouble(); } /// <summary> /// Implements the following function /// number sin(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double sin(double x){ return Math.Sin(x); } /// <summary> /// Implements the following function /// number asin(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double asin(double x){ return Math.Asin(x); } /// <summary> /// Implements the following function /// number cos(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double cos(double x){ return Math.Cos(x); } /// <summary> /// Implements the following function /// number acos(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double acos(double x){ return Math.Acos(x); } /// <summary> /// Implements the following function /// number tan(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double tan(double x){ return Math.Tan(x); } /// <summary> /// Implements the following function /// number atan(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double atan(double x){ return Math.Atan(x); } /// <summary> /// Implements the following function /// number atan2(number, number) /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double atan2(double x, double y){ return Math.Atan2(x,y); } /// <summary> /// Implements the following function /// number exp(number) /// </summary> /// <param name="x"></param> /// <returns></returns> public double exp(double x){ return Math.Exp(x); } } } --- NEW FILE: MethodRenamer.exe.config --- (This appears to be a binary file; contents omitted.) --- NEW FILE: ExsltRandom.cs --- #region using using System; using System.Xml.XPath; using System.Xml; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements the EXSLT functions in the http://exslt.org/random namespace. /// </summary> public class ExsltRandom { /// <summary> /// Implements the following function /// number+ random:random-sequence(number?, number?) /// </summary> public XPathNodeIterator randomSequence() { return randomSequenceImpl(1, (int)DateTime.Now.Ticks); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public XPathNodeIterator randomSequence_RENAME_ME() { return randomSequence(); } /// <summary> /// Implements the following function /// number+ random:random-sequence(number?, number?) /// </summary> public XPathNodeIterator randomSequence(double number) { return randomSequenceImpl(number, (int)DateTime.Now.Ticks); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public XPathNodeIterator randomSequence_RENAME_ME(double number) { return randomSequence(number); } /// <summary> /// Implements the following function /// number+ random:random-sequence(number?, number?) /// </summary> public XPathNodeIterator randomSequence(double number, double seed) { return randomSequenceImpl(number, (int)(seed % int.MaxValue)); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public XPathNodeIterator randomSequence_RENAME_ME(double number, double seed) { return randomSequence(number, seed); } /// <summary> /// random-sequence() implementation; /// </summary> /// <param name="number"></param> /// <param name="seed"></param> /// <returns></returns> private XPathNodeIterator randomSequenceImpl(double number, int seed) { XmlDocument doc = new XmlDocument(); doc.LoadXml("<randoms/>"); Random rand = new Random(seed); //Negative number is bad idea - fallback to default if (number < 0) number = 1; //we limit number of generated numbers to int.MaxValue if (number > int.MaxValue) number = int.MaxValue; for (int i=0; i<Convert.ToInt32(number); i++) { XmlElement elem = doc.CreateElement("random"); elem.InnerText = rand.NextDouble().ToString(); doc.DocumentElement.AppendChild(elem); } return doc.CreateNavigator().Select("/randoms/random"); } } } --- NEW FILE: Makefile --- all: @echo off @echo ########### Building Exslt library... csc /out:Mvp.Xml.Exslt.dll /target:library *.cs MultiOutput\*.cs /debug- /optimize+ nmake rename-methods rename-methods: @echo ########### Disassembing... ildasm Mvp.Xml.Exslt.dll /out=Mvp.Xml.Exslt.il /nobar @echo ########### Renaming methods... MethodRenamer.exe Mvp.Xml.Exslt.il Mvp.Xml.Exslt.Fixed.il @echo ########### Assembling library back... ilasm Mvp.Xml.Exslt.Fixed.il /RESOURCE=Mvp.Xml.Exslt.res /DLL /OUTPUT=Mvp.Xml.Exslt.dll /KEY=../../../../Global/v1/mvp-xml.snk nmake clean clean: @echo ########### Cleaning... del Mvp.Xml.Exslt.res del Mvp.Xml.Exslt.il del Mvp.Xml.Exslt.Fixed.il --- NEW FILE: ExsltDatesAndTimes.cs --- #region using using System; using System.Globalization; using System.Xml; using System.Xml.XPath; using System.Text; using System.Text.RegularExpressions; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements the EXSLT functions in the http://exslt.org/dates-and-times namespace. /// </summary> public class ExsltDatesAndTimes { private CultureInfo ci = new CultureInfo("en-US"); [...2135 lines suppressed...] /// string date:duration() /// </summary> /// <returns>seconds since the beginning of the epoch until now</returns> public string duration() { return duration(seconds()); } /// <summary> /// Implements the following function /// string date:duration(number) /// </summary> /// <param name="seconds"></param> /// <returns></returns> public string duration(double seconds) { return XmlConvert.ToString(new TimeSpan(0,0,(int)seconds)); } } } --- NEW FILE: GDNDatesAndTimes.cs --- #region using using System; using System.Globalization; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements additional functions in the /// "http://gotdotnet.com/exslt/dates-and-times" namespace. /// </summary> public class GDNDatesAndTimes : ExsltDatesAndTimes { #region date2:avg() /// <summary> /// Implements the following function /// string date2:avg(node-set) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-avg.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public string avg(XPathNodeIterator iterator) { TimeSpan sum = new TimeSpan(0,0,0,0); int count = iterator.Count; if(count == 0) { return ""; } try { while(iterator.MoveNext()) { sum = XmlConvert.ToTimeSpan(iterator.Current.Value).Add(sum); } } catch(FormatException) { return ""; } return duration(sum.TotalSeconds / count); } #endregion #region date2:min() /// <summary> /// Implements the following function /// string date2:min(node-set) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-min.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public string min(XPathNodeIterator iterator) { TimeSpan min, t; if(iterator.Count == 0) { return ""; } try { iterator.MoveNext(); min = XmlConvert.ToTimeSpan(iterator.Current.Value); while(iterator.MoveNext()) { t = XmlConvert.ToTimeSpan(iterator.Current.Value); min = (t < min)? t : min; } } catch(FormatException) { return ""; } return XmlConvert.ToString(min); } #endregion #region date2:max() /// <summary> /// Implements the following function /// string date2:max(node-set) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-max.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public string max(XPathNodeIterator iterator) { TimeSpan max, t; if(iterator.Count == 0) { return ""; } try { iterator.MoveNext(); max = XmlConvert.ToTimeSpan(iterator.Current.Value); while(iterator.MoveNext()) { t = XmlConvert.ToTimeSpan(iterator.Current.Value); max = (t > max)? t : max; } } catch(FormatException) { return ""; } return XmlConvert.ToString(max); } #endregion #region date2:day-abbreviation() /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public string dayAbbreviation_RENAME_ME(string d, string c) { return dayAbbreviation(d, c); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public new string dayAbbreviation_RENAME_ME(string c) { return dayAbbreviation(c); } /// <summary> /// Implements the following function /// string date2:day-abbreviation(string) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-day-abbreviation.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The abbreviated current day name according to /// specified culture or the empty string if the culture isn't /// supported.</returns> public new string dayAbbreviation(string culture) { try { CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetAbbreviatedDayName(DateTime.Now.DayOfWeek); } catch (Exception) { return ""; } } /// <summary> /// Implements the following function /// string date2:day-abbreviation(string, string) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-day-abbreviation.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The abbreviated day name of the specified date according to /// specified culture or the empty string if the input date is invalid or /// the culture isn't supported.</returns> public string dayAbbreviation(string d, string culture) { try { DateTZ date = new DateTZ(d); CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetAbbreviatedDayName(date.d.DayOfWeek); } catch (Exception) { return ""; } } #endregion #region date2:day-name() /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public string dayName_RENAME_ME(string d, string c) { return dayName(d, c); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public new string dayName_RENAME_ME(string c) { return dayName(c); } /// <summary> /// Implements the following function /// string date2:day-name(string, string?) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-day-name.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The day name of the specified date according to /// specified culture or the empty string if the input date is invalid or /// the culture isn't supported.</returns> public string dayName(string d, string culture) { try { DateTZ date = new DateTZ(d); CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetDayName(date.d.DayOfWeek); } catch (Exception) { return ""; } } /// <summary> /// Implements the following function /// string date2:day-name(string, string?) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-day-name.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The day name of the current date according to /// specified culture or the empty string if /// the culture isn't supported.</returns> public new string dayName(string culture) { try { CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetDayName(DateTime.Now.DayOfWeek); } catch (Exception) { return ""; } } #endregion #region date2:month-abbreviation() /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public string monthAbbreviation_RENAME_ME(string d, string c) { return monthAbbreviation(d, c); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public new string monthAbbreviation_RENAME_ME(string c) { return monthAbbreviation(c); } /// <summary> /// Implements the following function /// string date2:month-abbreviation(string) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-month-abbreviation.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The abbreviated current month name according to /// specified culture or the empty string if the culture isn't /// supported.</returns> public new string monthAbbreviation(string culture) { try { CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetAbbreviatedMonthName(DateTime.Now.Month); } catch (Exception) { return ""; } } /// <summary> /// Implements the following function /// string date2:month-abbreviation(string, string) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-month-abbreviation.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The abbreviated month name of the specified date according to /// specified culture or the empty string if the input date is invalid or /// the culture isn't supported.</returns> public string monthAbbreviation(string d, string culture) { try { DateTZ date = new DateTZ(d); CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetAbbreviatedMonthName(date.d.Month); } catch (Exception) { return ""; } } #endregion #region date2:month-name() /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public string monthName_RENAME_ME(string d, string c) { return monthName(d, c); } /// <summary> /// This wrapper method will be renamed during custom build /// to provide conformant EXSLT function name. /// </summary> public new string monthName_RENAME_ME(string c) { return monthName(c); } /// <summary> /// Implements the following function /// string date2:month-name(string, string?) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-month-name.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The month name of the specified date according to /// specified culture or the empty string if the input date is invalid or /// the culture isn't supported.</returns> public string monthName(string d, string culture) { try { DateTZ date = new DateTZ(d); CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetMonthName(date.d.Month); } catch (Exception) { return ""; } } /// <summary> /// Implements the following function /// string date2:month-name(string, string?) /// See http://www.xmland.net/exslt/doc/GDNDatesAndTimes-month-name.xml /// </summary> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> /// <returns>The month name of the current date according to /// specified culture or the empty string if /// the culture isn't supported.</returns> public new string monthName(string culture) { try { CultureInfo ci = new CultureInfo(culture); return ci.DateTimeFormat.GetMonthName(DateTime.Now.Month); } catch (Exception) { return ""; } } #endregion } } --- NEW FILE: PostBuildEvent.bat --- @echo off @echo ########### Setting environment variables call "D:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\..\Tools\vsvars32.bat" nmake if errorlevel 1 goto CSharpReportError goto CSharpEnd :CSharpReportError echo Project error: A tool returned an error code from the build event exit 1 :CSharpEnd --- NEW FILE: GDNRegularExpressions.cs --- #region using using System; using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements additional functions in the http://gotdotnet.com/exslt/regular-expressions namespace. /// </summary> public class GDNRegularExpressions { /// <summary> /// Implements the following function /// node-set tokenize(string, string) /// </summary> /// <param name="str"></param> /// <param name="regexp"></param> /// <returns>This function breaks the input string into a sequence of strings, /// treating any substring that matches the regexp as a separator. /// The separators themselves are not returned. /// The matching strings are returned as a set of 'match' elements.</returns> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public XPathNodeIterator tokenize(string str, string regexp) { RegexOptions options = RegexOptions.ECMAScript; XmlDocument doc = new XmlDocument(); doc.LoadXml("<matches/>"); Regex regex = new Regex(regexp, options); foreach(string match in regex.Split(str)) { XmlElement elem = doc.CreateElement("match"); elem.InnerText = match; doc.DocumentElement.AppendChild(elem); } return doc.CreateNavigator().Select("//match"); } /// <summary> /// Implements the following function /// node-set tokenize(string, string, string) /// </summary> /// <param name="str"></param> /// <param name="regexp"></param> /// <param name="flags"></param> /// <returns>This function breaks the input string into a sequence of strings, /// treating any substring that matches the regexp as a separator. /// The separators themselves are not returned. /// The matching strings are returned as a set of 'match' elements.</returns> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public XPathNodeIterator tokenize(string str, string regexp, string flags) { RegexOptions options = RegexOptions.ECMAScript; if(flags.IndexOf("m")!= -1) { options |= RegexOptions.Multiline; } if(flags.IndexOf("i")!= -1) { options |= RegexOptions.IgnoreCase; } XmlDocument doc = new XmlDocument(); doc.LoadXml("<matches/>"); Regex regex = new Regex(regexp, options); foreach(string match in regex.Split(str)) { XmlElement elem = doc.CreateElement("match"); elem.InnerText = match; doc.DocumentElement.AppendChild(elem); } return doc.CreateNavigator().Select("//match"); } } } --- NEW FILE: ExsltTransform.cs --- #region using using System; using System.Xml.Xsl; using System.Xml; using System.Xml.XPath; using System.IO; using System.Text; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// Enumeration used to indicate an EXSLT function namespace. /// </summary> [Flags] public enum ExsltFunctionNamespace{ None = 0, Common = 1, DatesAndTimes = 2, Math = 4, RegularExpressions = 8, Sets = 16, Strings = 32, GDNDatesAndTimes = 64, GDNSets = 128, GDNMath = 256, GDNRegularExpressions = 512, GDNStrings = 1024, Random = 2048, GDNDynamic = 4096, AllExslt = Common | DatesAndTimes | Math | Random | RegularExpressions | Sets | Strings, All = Common | DatesAndTimes | Math | Random | RegularExpressions | Sets | Strings | GDNDatesAndTimes | GDNSets | GDNMath | GDNRegularExpressions | GDNStrings | GDNDynamic } /// <summary> /// Transforms XML data using an XSLT stylesheet. Supports a number of EXSLT as /// defined at http://www.exslt.org /// </summary> /// <remarks> /// XslTransform supports the XSLT 1.0 syntax. The XSLT stylesheet must use the /// namespace http://www.w3.org/1999/XSL/Transform. Additional arguments can also be /// added to the stylesheet using the XsltArgumentList class. /// This class contains input parameters for the stylesheet and extension objects which can be called from the stylesheet. /// This class also recognizes functions from the following namespaces /// * http://exslt.org/common /// * http://exslt.org/dates-and-times /// * http://exslt.org/math /// * http://exslt.org/random /// * http://exslt.org/regular-expressions /// * http://exslt.org/sets /// * http://exslt.org/strings /// * http://gotdotnet.com/exslt/dates-and-times /// * http://gotdotnet.com/exslt/math /// * http://gotdotnet.com/exslt/regular-expressions /// * http://gotdotnet.com/exslt/sets /// * http://gotdotnet.com/exslt/strings /// * http://gotdotnet.com/exslt/dynamic /// </remarks> public class ExsltTransform { #region Private Fields and Properties /// <summary> /// Sync object. /// </summary> private object sync = new object(); /// <summary> /// The XslTransform object wrapped by this class. /// </summary> private XslTransform xslTransform; /// <summary> /// Bitwise enumeration used to specify which EXSLT functions should be accessible to /// the ExsltTransform object. The default value is ExsltFunctionNamespace.All /// </summary> private ExsltFunctionNamespace _supportedFunctions = ExsltFunctionNamespace.All; /// <summary> /// Extension object which implements the functions in the http://exslt.org/common namespace /// </summary> private ExsltCommon exsltCommon = new ExsltCommon(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/math namespace /// </summary> private ExsltMath exsltMath = new ExsltMath(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/random namespace /// </summary> private ExsltRandom exsltRandom = new ExsltRandom(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/dates-and-times namespace /// </summary> private ExsltDatesAndTimes exsltDatesAndTimes = new ExsltDatesAndTimes(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/regular-expressions namespace /// </summary> private ExsltRegularExpressions exsltRegularExpressions = new ExsltRegularExpressions(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/strings namespace /// </summary> private ExsltStrings exsltStrings = new ExsltStrings(); /// <summary> /// Extension object which implements the functions in the http://exslt.org/sets namespace /// </summary> private ExsltSets exsltSets = new ExsltSets(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/dates-and-times namespace /// </summary> private GDNDatesAndTimes gdnDatesAndTimes = new GDNDatesAndTimes(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/regular-expressions namespace /// </summary> private GDNRegularExpressions gdnRegularExpressions = new GDNRegularExpressions(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/math namespace /// </summary> private GDNMath gdnMath = new GDNMath(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/sets namespace /// </summary> private GDNSets gdnSets = new GDNSets(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/strings namespace /// </summary> private GDNStrings gdnStrings = new GDNStrings(); /// <summary> /// Extension object which implements the functions in the http://gotdotnet.com/exslt/dynamic namespace /// </summary> private GDNDynamic gdnDynamic = new GDNDynamic(); /// <summary> /// Boolean flag used to specify whether multiple output is supported. /// </summary> private bool _multiOutput = false; #endregion #region Public Fields and Properties /// <summary> /// Sets the XmlResolver used to resolve external resources when the /// Transform method is called. /// </summary> public XmlResolver XmlResolver { set { this.xslTransform.XmlResolver = value; } } /// <summary> /// Bitwise enumeration used to specify which EXSLT functions should be accessible to /// the ExsltTransform object. The default value is ExsltFunctionNamespace.All /// </summary> public ExsltFunctionNamespace SupportedFunctions{ set { if (Enum.IsDefined(typeof(ExsltFunctionNamespace), value)) this._supportedFunctions = value; } get { return this._supportedFunctions; } } /// <summary> /// Boolean flag used to specify whether multiple output (via exsl:document) is /// supported. /// Note: This property is ignored (hence multiple output is not supported) when /// transformation is done to XmlReader or XmlWriter (use overloaded method, /// which transforms to MultiXmlTextWriter instead). /// Note: Because of some restrictions and slight overhead this feature is /// disabled by default. If you need multiple output support, set this property to /// true before the Transform() call. /// </summary> public bool MultiOutput { get { return _multiOutput; } set { _multiOutput = value; } } #endregion #region Constructors /// <summary> /// Constructor initializes class. /// </summary> public ExsltTransform(){ this.xslTransform = new XslTransform(); } #endregion #region Load() method Overloads /// <summary> Loads the XSLT stylesheet contained in the IXPathNavigable</summary> public void Load(IXPathNavigable ixn){ this.xslTransform.Load(ixn); } /// <summary> Loads the XSLT stylesheet specified by a URL</summary> public void Load(string s){ this.xslTransform.Load(s); } /// <summary> Loads the XSLT stylesheet contained in the XmlReader</summary> public void Load(XmlReader reader){ this.xslTransform.Load(reader); } /// <summary> Loads the XSLT stylesheet contained in the XPathNavigator</summary> public void Load(XPathNavigator navigator){ this.xslTransform.Load(navigator); } /// <summary> Loads the XSLT stylesheet contained in the IXPathNavigable</summary> public void Load(IXPathNavigable ixn, XmlResolver resolver){ this.xslTransform.Load(ixn, resolver); } /// <summary> Loads the XSLT stylesheet specified by a URL</summary> public void Load(string s, XmlResolver resolver){ this.xslTransform.Load(s, resolver); } /// <summary> Loads the XSLT stylesheet contained in the XmlReader</summary> public void Load(XmlReader reader, XmlResolver resolver){ this.xslTransform.Load(reader, resolver); } /// <summary> Loads the XSLT stylesheet contained in the XPathNavigator</summary> public void Load(XPathNavigator navigator, XmlResolver resolver) {this.xslTransform.Load(navigator, resolver); } #endregion #region Transform() method Overloads /// <summary> Transforms the XML data in the IXPathNavigable using the specified args and outputs the result to an XmlReader</summary> public XmlReader Transform(IXPathNavigable ixn, XsltArgumentList arglist) { return this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist)); } /// <summary> Transforms the XML data in the input file and outputs the result to an output file</summary> public void Transform(string infile, string outfile) { // Use using so that the file is not held open after the call using (StreamWriter outStream = new StreamWriter(outfile)) { if (_multiOutput) this.xslTransform.Transform(new XPathDocument(infile), this.AddExsltExtensionObjects(null), new MultiXmlTextWriter(outStream)); else this.xslTransform.Transform(new XPathDocument(infile), this.AddExsltExtensionObjects(null), outStream); } } /// <summary> Transforms the XML data in the XPathNavigator using the specified args and outputs the result to an XmlReader</summary> public XmlReader Transform(XPathNavigator navigator, XsltArgumentList arglist) { return this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist)); } /// <summary> Transforms the XML data in the IXPathNavigable using the specified args and outputs the result to a Stream</summary> public void Transform(IXPathNavigable ixn, XsltArgumentList arglist, Stream stream) { if (_multiOutput) this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), new MultiXmlTextWriter(stream, Encoding.UTF8)); else this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), stream); } /// <summary> Transforms the XML data in the IXPathNavigable using the specified args and outputs the result to a TextWriter</summary> public void Transform(IXPathNavigable ixn, XsltArgumentList arglist, TextWriter writer) { if (_multiOutput) this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), new MultiXmlTextWriter(writer)); else this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), writer); } /// <summary> Transforms the XML data in the IXPathNavigable using the specified args and outputs the result to an XmlWriter</summary> public void Transform(IXPathNavigable ixn, XsltArgumentList arglist, XmlWriter writer) { this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), writer); } /// <summary> Transforms the XML data in the IXPathNavigable using the specified args and outputs the result to an MultiXmlTextWriter</summary> public void Transform(IXPathNavigable ixn, XsltArgumentList arglist, MultiXmlTextWriter writer) { this.xslTransform.Transform(ixn, this.AddExsltExtensionObjects(arglist), writer); } /// <summary> Transforms the XML data in the XPathNavigator using the specified args and outputs the result to a Stream</summary> public void Transform(XPathNavigator navigator, XsltArgumentList arglist, Stream stream) { if (_multiOutput) this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), new MultiXmlTextWriter(stream, Encoding.UTF8)); else this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), stream); } /// <summary> Transforms the XML data in the XPathNavigator using the specified args and outputs the result to a TextWriter</summary> public void Transform(XPathNavigator navigator, XsltArgumentList arglist, TextWriter writer) { if (_multiOutput) this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), new MultiXmlTextWriter(writer)); else this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), writer); } /// <summary> Transforms the XML data in the XPathNavigator using the specified args and outputs the result to an XmlWriter</summary> public void Transform(XPathNavigator navigator, XsltArgumentList arglist, XmlWriter writer) { this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), writer); } /// <summary> Transforms the XML data in the XPathNavigator using the specified args and outputs the result to an MultiXmlTextWriter</summary> public void Transform(XPathNavigator navigator, XsltArgumentList arglist, MultiXmlTextWriter writer) { this.xslTransform.Transform(navigator, this.AddExsltExtensionObjects(arglist), writer); } #endregion #region Public Methods #endregion #region Private Methods /// <summary> /// Adds the objects that implement the EXSLT extensions to the provided argument /// list. The extension objects added depend on the value of the SupportedFunctions /// property. /// </summary> /// <param name="arglist">The argument list</param> /// <returns>An XsltArgumentList containing the contents of the list passed in /// and objects that implement the EXSLT. </returns> /// <remarks>If null is passed in then a new XsltArgumentList is constructed. </remarks> private XsltArgumentList AddExsltExtensionObjects(XsltArgumentList list){ if(list == null){ list = new XsltArgumentList(); } lock (sync) { //remove all our extension objects in case the XSLT argument list is being reused list.RemoveExtensionObject(ExsltNamespaces.Common); list.RemoveExtensionObject(ExsltNamespaces.Math); list.RemoveExtensionObject(ExsltNamespaces.Random); list.RemoveExtensionObject(ExsltNamespaces.DatesAndTimes); list.RemoveExtensionObject(ExsltNamespaces.RegularExpressions); list.RemoveExtensionObject(ExsltNamespaces.Strings); list.RemoveExtensionObject(ExsltNamespaces.Sets); list.RemoveExtensionObject(ExsltNamespaces.GDNDatesAndTimes); list.RemoveExtensionObject(ExsltNamespaces.GDNMath); list.RemoveExtensionObject(ExsltNamespaces.GDNRegularExpressions); list.RemoveExtensionObject(ExsltNamespaces.GDNSets); list.RemoveExtensionObject(ExsltNamespaces.GDNStrings); list.RemoveExtensionObject(ExsltNamespaces.GDNDynamic); //add extension objects as specified by SupportedFunctions if((this.SupportedFunctions & ExsltFunctionNamespace.Common) > 0) { list.AddExtensionObject(ExsltNamespaces.Common, this.exsltCommon); } if((this.SupportedFunctions & ExsltFunctionNamespace.Math) > 0) { list.AddExtensionObject(ExsltNamespaces.Math, this.exsltMath); } if((this.SupportedFunctions & ExsltFunctionNamespace.Random) > 0) { list.AddExtensionObject(ExsltNamespaces.Random, this.exsltRandom); } if((this.SupportedFunctions & ExsltFunctionNamespace.DatesAndTimes) > 0) { list.AddExtensionObject(ExsltNamespaces.DatesAndTimes, this.exsltDatesAndTimes); } if((this.SupportedFunctions & ExsltFunctionNamespace.RegularExpressions) > 0) { list.AddExtensionObject(ExsltNamespaces.RegularExpressions, this.exsltRegularExpressions); } if((this.SupportedFunctions & ExsltFunctionNamespace.Strings) > 0) { list.AddExtensionObject(ExsltNamespaces.Strings, this.exsltStrings); } if((this.SupportedFunctions & ExsltFunctionNamespace.Sets) > 0) { list.AddExtensionObject(ExsltNamespaces.Sets, this.exsltSets); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNDatesAndTimes) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNDatesAndTimes, this.gdnDatesAndTimes); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNMath) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNMath, this.gdnMath); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNRegularExpressions) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNRegularExpressions, this.gdnRegularExpressions); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNSets) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNSets, this.gdnSets); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNStrings) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNStrings, this.gdnStrings); } if((this.SupportedFunctions & ExsltFunctionNamespace.GDNDynamic) > 0) { list.AddExtensionObject(ExsltNamespaces.GDNDynamic, this.gdnDynamic); } } return list; } #endregion } } --- NEW FILE: AssemblyInfo.cs --- using System; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly: AssemblyTitle("Mvp.Xml.Exslt")] [assembly: AssemblyDescription("MVP XML Library - EXSLT.NET Module")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.3.*")] // // In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // // Use the attributes below to control which key is used for signing. // // Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. // (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. // (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\<configuration>. For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. // [assembly: AssemblyDelaySign(false)] //Signed in custom build - see Makefile //[assembly: AssemblyKeyFile("exslt.snk")] [assembly: AssemblyKeyName("")] --- NEW FILE: GDNMath.cs --- #region using using System; using System.Xml; using System.Xml.XPath; #endregion namespace Mvp.Xml.Exslt { /// <summary> /// This class implements addditional functions in the http://gotdotnet.com/exslt/math namespace. /// </summary> public class GDNMath { /// <summary> /// Implements the following function /// number avg(node-set) /// </summary> /// <param name="iterator"></param> /// <returns>The average of all the value of all the nodes in the /// node set</returns> /// <remarks>THIS FUNCTION IS NOT PART OF EXSLT!!!</remarks> public double avg(XPathNodeIterator iterator) { double sum = 0; int count = iterator.Count; if(count == 0) { return Double.NaN; } try { while(iterator.MoveNext()) { sum += XmlConvert.ToDouble(iterator.Current.Value); } } catch(FormatException) { return Double.NaN; } return sum / count; } } } --- NEW FILE: install.cmd --- gacutil /if Mvp.Xml.Exslt.dll --- NEW FILE: Exslt.csproj.user --- <VisualStudioProject> <CSHARP LastOpenVersion = "7.10.3077" > <Build> <Settings ReferencePath = "" > <Config Name = "Debug" EnableASPDebugging = "false" EnableASPXDebugging = "false" EnableUnmanagedDebugging = "false" EnableSQLServerDebugging = "false" RemoteDebugEnabled = "false" RemoteDebugMachine = "" StartAction = "Project" StartArguments = "" StartPage = "" StartProgram = "" StartURL = "" StartWorkingDirectory = "" StartWithIE = "false" /> <Config Name = "Release" EnableASPDebugging = "false" EnableASPXDebugging = "false" EnableUnmanagedDebugging = "false" EnableSQLServerDebugging = "false" RemoteDebugEnabled = "false" RemoteDebugMachine = "" StartAction = "Project" StartArguments = "" StartPage = "" StartProgram = "" StartURL = "" StartWorkingDirectory = "" StartWithIE = "false" /> </Settings> </Build> <OtherProjectSettings CopyProjectDestinationFolder = "" CopyProjectUncPath = "" CopyProjectOption = "0" ProjectView = "ProjectFiles" ProjectTrust = "0" /> </CSHARP> </VisualStudioProject> --- NEW FILE: .cvsignore --- bin obj *.user *.suo *.dll *.pdb --- NEW FILE: index.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>EXSLT.NET version 1.1</title> <meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> <style type="text/css"> BODY { font-family:Verdana, Tahoma, Arial; font-size:10pt; } </style> </head> <body> <H2 align="center">EXSLT.NET version 1.1</H2> <H3>Contents</H3> <OL> <LI> <A href="#whatis">What Is EXSLT.NET</A> <LI> <A href="#new">What's New In This Version</A> <LI> <A href="#install">Installation</A> <LI> <A href="#build">Building</A> <LI> <A href="#usage">Usage</A> <LI> <A href="#funclist">Extension Functions and Elements</A> <LI> <A href="#multiout">Multiple Output</A> <LI> <A href="#credits">Credits And Legal Stuff</A> <LI> <A href="#refs">References</A></LI></OL> <H3><a name="whatis">1. What Is EXSLT.NET</a></H3> <P>EXSLT.NET library is community-developed implementation of the <A href="http://exslt.org"> EXSLT</A> extensions to XSLT for the .NET platform. EXSLT.NET fully implements the following EXSLT modules: <A href="http://exslt.org/date/index.html">Dates and Times</A>, <A href="http://exslt.org/exsl/index.html">Common</A>, <A href="http://exslt.org/math/index.html"> Math</A>, <A href="http://exslt.org/random/index.html">Random</A>, <A href="http://exslt.org/regexp/index.html"> Regular Expressions</A>, <A href="http://exslt.org/set/index.html">Sets</A> and <A href="http://exslt.org/str/index.html">Strings</A>. In addition EXSLT.NET library provides proprietary set of useful extension functions. See full list of supported extension functions and elements in "<A href="#funclist">Extension Functions and Elements</A>" section. For more info about EXSLT and EXSLT.NET see <A href="#refs">References</A>. </P> <H3><a name="new">2. What's New In This Version</a></H3> <UL> <LI> New EXSLT extension functions has been implemented: <A href="http://exslt.org/str/functions/encode-uri/index.html"> <FONT face="Courier New">str:encode-uri()</FONT></A>, <A href="http://exslt.org/str/functions/decode-uri/index.html"> <FONT face="Courier New">str:decode-uri()</FONT></A>, <A href="http://exslt.org/random/functions/random-sequence/index.html"> <FONT face="Courier New">random:random-sequence()</FONT></A>. <LI> New EXSLT.NET extension functions has been implemented: <FONT face="Courier New"><A href="doc/GDNDynamic-evaluate.xml"> dyn2:evaluate()</A></FONT>, which allows to evaluate a string as an XPath expression, <FONT face="Courier New"><A href="doc/GDNDatesAndTimes-day-name.xml">date2:day-name()</A></FONT>, <FONT face="Courier New"><A href="doc/GDNDatesAndTimes-day-abbreviation.xml">date2:day-abbreviation()</A></FONT>, <FONT face="Courier New"><A href="doc/GDNDatesAndTimes-month-name.xml">date2:month-name()</A></FONT> and <FONT face="Courier New"><A href="doc/GDNDatesAndTimes-month-abbreviation.xml">date2:month-abbreviation()</A></FONT> - these functions are culture-aware versions of the appropriate EXSLT functions. <LI> Support for time zone in date-time functions has been implemented. <LI> Multithreading issue with <FONT face="Courier New">ExsltTransform</FONT> class has been fixed. Now <FONT face="Courier New">ExsltTransform</FONT> class is thread-safe for <FONT face="Courier New">Transform()</FONT> method calls just like the <FONT face="Courier New">System.Xml.Xsl.XslTransform</FONT> class. <LI> Lots of minor bugs has been fixed. See EXSLT.NET <A href="http://www.gotdotnet.com/workspaces/bugtracker/home.aspx?id=201eb290-5bf0-4452-9bf7-d21d39268f36"> bug tracker</A> for more info. <LI> We switched to Visual Studio .NET 2003, so building of the project has been greatly simplified. <LI> Complete suite of NUnit tests for each extension function has been implemented (<FONT face="Courier New">ExsltTest</FONT> project).</LI></UL> <H3>3<a name="install">. Installation</a></H3> <P>EXSLT.NET is designed as a component for .NET Framework and actually doesn't require any installation. You can use <FONT face="Courie... [truncated message content] |