Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
//
// Attribute.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
//
// (C) 2003 Oleg Tkachenko
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Xml;
namespace Mono.Xml.Xsl {
/// <summary>
/// XML attribute.
/// </summary>
internal struct Attribute {
public string Prefix;
public string Namespace;
public string LocalName;
public string Value;
public Attribute (string prefix, string namespaceUri, string localName, string value)
{
this.Prefix = prefix;
this.Namespace = namespaceUri;
this.LocalName = localName;
this.Value = value;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
//
// Debug.cs
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) 2003 Ben Maurer
// (C) 2003 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Globalization;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace Mono.Xml.Xsl {
internal class Debug {
[System.Diagnostics.Conditional("_DEBUG")]
internal static void TraceContext(XPathNavigator context) {
string output = "(null)";
if (context != null) {
context = context.Clone ();
switch (context.NodeType) {
case XPathNodeType.Element:
output = string.Format("<{0}:{1}", context.Prefix, context.LocalName);
for (bool attr = context.MoveToFirstAttribute(); attr; attr = context.MoveToNextAttribute()) {
output += string.Format(CultureInfo.InvariantCulture, " {0}:{1}={2}", context.Prefix, context.LocalName, context.Value);
}
output += ">";
break;
default:
break;
}
}
WriteLine(output);
}
[System.Diagnostics.Conditional("DEBUG")]
internal static void Assert (bool condition, string message)
{
if (!condition)
throw new XsltException (message, null);
}
[System.Diagnostics.Conditional("_DEBUG")]
internal static void WriteLine (object value)
{
Console.Error.WriteLine (value);
}
[System.Diagnostics.Conditional("_DEBUG")]
internal static void WriteLine (string message)
{
Console.Error.WriteLine (message);
}
//static Stack eleStack = new Stack ();
[System.Diagnostics.Conditional("DEBUG")]
internal static void EnterNavigator (Compiler c)
{
//eleStack.Push (c.Input.Clone ());
}
[System.Diagnostics.Conditional("DEBUG")]
internal static void ExitNavigator (Compiler c)
{
//XPathNavigator x = (XPathNavigator)eleStack.Pop();
//if (!x.IsSamePosition (c.Input))
// throw new Exception ("Position must be the same on enter/exit. Enter node: " + x.Name + " exit node " + c.Input.Name);
}
}
}

View File

@@ -0,0 +1,66 @@
//
// Emitter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
// Atsushi Enomoto (atsushi@ximian.com)
// (C) 2003 Oleg Tkachenko
// (C) 2004 Novell inc.
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Text;
namespace Mono.Xml.Xsl {
/// <summary>
/// Abstract emitter. Implementations of this class deals with outputting
/// result tree to specific output format, such as XML, HTML, Text.
/// Implementations for additional formats (e.g. XHTML) as well as custom
/// implementations may be supported either.
/// </summary>
internal abstract class Emitter {
public abstract void WriteStartDocument (Encoding encoding, StandaloneType standalone);
public abstract void WriteEndDocument ();
public abstract void WriteDocType (string type, string publicId, string systemId);
public abstract void WriteStartElement (string prefix, string localName, string nsURI);
public abstract void WriteEndElement ();
public virtual void WriteFullEndElement ()
{
WriteEndElement ();
}
public abstract void WriteAttributeString (string prefix, string localName, string nsURI, string value);
public abstract void WriteComment (string text);
public abstract void WriteProcessingInstruction (string name, string text);
public abstract void WriteString (string text);
public abstract void WriteCDataSection (string text);
public abstract void WriteRaw (string data);
public abstract void Done ();
public virtual void WriteWhitespace (string text)
{
WriteString (text);
}
}
}

View File

@@ -0,0 +1,388 @@
//
// GenericOutputter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) 2003 Oleg Tkachenko, Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Xml;
using System.IO;
using System.Text;
namespace Mono.Xml.Xsl
{
/// <summary>
/// Generic implemenatation of the Outputter.
/// Works as a buffer between Transformation classes and an Emitter.
/// Implements attributes dublicate checking, nemaspace stuff and
/// choosing of right Emitter implementation.
/// </summary>
internal class GenericOutputter : Outputter {
private Hashtable _outputs;
//Current xsl:output
private XslOutput _currentOutput;
//Underlying emitter
private Emitter _emitter;
// destination TextWriter,
// which is pended until the actual output is determined.
private TextWriter pendingTextWriter;
// also, whitespaces before the first element are cached.
StringBuilder pendingFirstSpaces;
//Outputting state
private WriteState _state;
// Collection of pending attributes. TODO: Can we make adding an attribute
// O(1)? I'm not sure it is that important (this would only really make a difference
// if elements had like 10 attributes, which is very rare).
Attribute [] pendingAttributes = new Attribute [10];
int pendingAttributesPos = 0;
//Namespace manager. Subject to optimization.
private XmlNamespaceManager _nsManager;
private ListDictionary _currentNamespaceDecls;
// See CheckState(). This is just a cache.
private ArrayList newNamespaces = new ArrayList();
//Name table
private NameTable _nt;
// Specified encoding (for TextWriter output)
Encoding _encoding;
//Determines whether xsl:copy can output attribute-sets or not.
bool _canProcessAttributes;
bool _insideCData;
// bool _isVariable;
bool _omitXmlDeclaration;
int _xpCount;
private GenericOutputter (Hashtable outputs, Encoding encoding)
{
_encoding = encoding;
_outputs = outputs;
_currentOutput = (XslOutput)outputs [String.Empty];
_state = WriteState.Prolog;
//TODO: Optimize using nametable
_nt = new NameTable ();
_nsManager = new XmlNamespaceManager (_nt);
_currentNamespaceDecls = new ListDictionary ();
_omitXmlDeclaration = false;
}
public GenericOutputter (XmlWriter writer, Hashtable outputs, Encoding encoding)
: this (writer, outputs, encoding, false)
{
}
internal GenericOutputter (XmlWriter writer, Hashtable outputs, Encoding encoding, bool isVariable)
: this (outputs, encoding)
{
_emitter = new XmlWriterEmitter (writer);
_state = writer.WriteState;
// _isVariable = isVariable;
_omitXmlDeclaration = true; // .Net never writes XML declaration via XmlWriter
}
public GenericOutputter (TextWriter writer, Hashtable outputs, Encoding encoding)
: this (outputs, encoding)
{
this.pendingTextWriter = writer;
}
internal GenericOutputter (TextWriter writer, Hashtable outputs)
: this (writer, outputs, null)
{
}
internal GenericOutputter (XmlWriter writer, Hashtable outputs)
: this (writer, outputs, null)
{
}
private Emitter Emitter {
get {
if (_emitter == null)
DetermineOutputMethod (null, null);
return _emitter;
}
}
private void DetermineOutputMethod (string localName, string ns)
{
XslOutput xslOutput = (XslOutput)_outputs [String.Empty];
switch (xslOutput.Method) {
default: // .Custom format is not supported, only handled as unknown
case OutputMethod.Unknown:
if (localName != null && String.Compare (localName, "html", true, CultureInfo.InvariantCulture) == 0 && ns == String.Empty)
goto case OutputMethod.HTML;
goto case OutputMethod.XML;
case OutputMethod.HTML:
_emitter = new HtmlEmitter (pendingTextWriter, xslOutput);
break;
case OutputMethod.XML:
XmlTextWriter w = new XmlTextWriter (pendingTextWriter);
if (xslOutput.Indent == "yes")
w.Formatting = Formatting.Indented;
_emitter = new XmlWriterEmitter (w);
if (!_omitXmlDeclaration && !xslOutput.OmitXmlDeclaration)
_emitter.WriteStartDocument (
_encoding != null ? _encoding : xslOutput.Encoding,
xslOutput.Standalone);
break;
case OutputMethod.Text:
_emitter = new TextEmitter (pendingTextWriter);
break;
}
pendingTextWriter = null;
}
/// <summary>
/// Checks output state and flushes pending attributes and namespaces
/// when it's appropriate.
/// </summary>
private void CheckState ()
{
if (_state == WriteState.Element) {
//Emit pending attributes
_nsManager.PushScope ();
foreach (string prefix in _currentNamespaceDecls.Keys)
{
string uri = _currentNamespaceDecls [prefix] as string;
if (_nsManager.LookupNamespace (prefix, false) == uri)
continue;
newNamespaces.Add (prefix);
_nsManager.AddNamespace (prefix, uri);
}
for (int i = 0; i < pendingAttributesPos; i++)
{
Attribute attr = pendingAttributes [i];
string prefix = attr.Prefix;
if (prefix == XmlNamespaceManager.PrefixXml &&
attr.Namespace != XmlNamespaceManager.XmlnsXml)
// don't allow mapping from "xml" to other namespaces.
prefix = String.Empty;
string existing = _nsManager.LookupPrefix (attr.Namespace, false);
if (prefix.Length == 0 && attr.Namespace.Length > 0)
prefix = existing;
if (attr.Namespace.Length > 0) {
if (prefix == null || prefix == String.Empty)
{ // ADD
// empty prefix is not allowed
// for non-local attributes.
prefix = "xp_" + _xpCount++;
//if (existing != prefix) {
while (_nsManager.LookupNamespace (prefix) != null)
prefix = "xp_" + _xpCount++;
newNamespaces.Add (prefix);
_currentNamespaceDecls.Add (prefix, attr.Namespace);
_nsManager.AddNamespace (prefix, attr.Namespace);
//}
} // ADD
}
Emitter.WriteAttributeString (prefix, attr.LocalName, attr.Namespace, attr.Value);
}
for (int i = 0; i < newNamespaces.Count; i++)
{
string prefix = (string) newNamespaces [i];
string uri = _currentNamespaceDecls [prefix] as string;
if (prefix != String.Empty)
Emitter.WriteAttributeString ("xmlns", prefix, XmlNamespaceManager.XmlnsXmlns, uri);
else
Emitter.WriteAttributeString (String.Empty, "xmlns", XmlNamespaceManager.XmlnsXmlns, uri);
}
_currentNamespaceDecls.Clear ();
//Attributes flushed, state is Content now
_state = WriteState.Content;
newNamespaces.Clear ();
}
_canProcessAttributes = false;
}
#region Outputter's methods implementation
public override void WriteStartElement (string prefix, string localName, string nsURI)
{
if (_emitter == null) {
this.DetermineOutputMethod (localName, nsURI);
if (pendingFirstSpaces != null) {
WriteWhitespace (pendingFirstSpaces.ToString ());
pendingFirstSpaces = null;
}
}
if (_state == WriteState.Prolog) {
//Seems to be the first element - take care of Doctype
// Note that HTML does not require SYSTEM identifier.
if (_currentOutput.DoctypePublic != null || _currentOutput.DoctypeSystem != null)
Emitter.WriteDocType (prefix + (prefix==null? ":" : "") + localName,
_currentOutput.DoctypePublic, _currentOutput.DoctypeSystem);
}
CheckState ();
if (nsURI == String.Empty)
prefix = String.Empty;
Emitter.WriteStartElement (prefix, localName, nsURI);
_state = WriteState.Element;
if (_nsManager.LookupNamespace (prefix, false) != nsURI)
// _nsManager.AddNamespace (prefix, nsURI);
_currentNamespaceDecls [prefix] = nsURI;
pendingAttributesPos = 0;
_canProcessAttributes = true;
}
public override void WriteEndElement ()
{
WriteEndElementInternal (false);
}
public override void WriteFullEndElement()
{
WriteEndElementInternal (true);
}
private void WriteEndElementInternal (bool fullEndElement)
{
CheckState ();
if (fullEndElement)
Emitter.WriteFullEndElement ();
else
Emitter.WriteEndElement ();
_state = WriteState.Content;
//Pop namespace scope
_nsManager.PopScope ();
}
public override void WriteAttributeString (string prefix, string localName, string nsURI, string value)
{
//Put attribute to pending attributes collection, replacing namesake one
for (int i = 0; i < pendingAttributesPos; i++) {
Attribute attr = pendingAttributes [i];
if (attr.LocalName == localName && attr.Namespace == nsURI) {
pendingAttributes [i].Value = value;
pendingAttributes [i].Prefix = prefix;
return;
}
}
if (pendingAttributesPos == pendingAttributes.Length) {
Attribute [] old = pendingAttributes;
pendingAttributes = new Attribute [pendingAttributesPos * 2 + 1];
if (pendingAttributesPos > 0)
Array.Copy (old, 0, pendingAttributes, 0, pendingAttributesPos);
}
pendingAttributes [pendingAttributesPos].Prefix = prefix;
pendingAttributes [pendingAttributesPos].Namespace = nsURI;
pendingAttributes [pendingAttributesPos].LocalName = localName;
pendingAttributes [pendingAttributesPos].Value = value;
pendingAttributesPos++;
}
public override void WriteNamespaceDecl (string prefix, string nsUri)
{
if (_nsManager.LookupNamespace (prefix, false) == nsUri)
return; // do nothing
for (int i = 0; i < pendingAttributesPos; i++) {
Attribute attr = pendingAttributes [i];
if (attr.Prefix == prefix || attr.Namespace == nsUri)
return; //don't touch explicitly declared attributes
}
if (_currentNamespaceDecls [prefix] as string != nsUri)
_currentNamespaceDecls [prefix] = nsUri;
}
public override void WriteComment (string text)
{
CheckState ();
Emitter.WriteComment (text);
}
public override void WriteProcessingInstruction (string name, string text)
{
CheckState ();
Emitter.WriteProcessingInstruction (name, text);
}
public override void WriteString (string text)
{
CheckState ();
if (_insideCData)
Emitter.WriteCDataSection (text);
// This weird check is required to reject Doctype
// after non-whitespace nodes but also to allow
// Doctype after whitespace nodes. It especially
// happens when there is an xsl:text before the
// document element (e.g. BVTs_bvt066 testcase).
else if (_state != WriteState.Content &&
text.Length > 0 && XmlChar.IsWhitespace (text))
Emitter.WriteWhitespace (text);
else
Emitter.WriteString (text);
}
public override void WriteRaw (string data)
{
CheckState ();
Emitter.WriteRaw (data);
}
public override void WriteWhitespace (string text)
{
if (_emitter == null) {
if (pendingFirstSpaces == null)
pendingFirstSpaces = new StringBuilder ();
pendingFirstSpaces.Append (text);
if (_state == WriteState.Start)
_state = WriteState.Prolog;
} else {
CheckState ();
Emitter.WriteWhitespace (text);
}
}
public override void Done ()
{
Emitter.Done ();
_state = WriteState.Closed;
}
public override bool CanProcessAttributes {
get { return _canProcessAttributes; }
}
public override bool InsideCDataSection {
get { return _insideCData; }
set { _insideCData = value; }
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
//
// MSXslScriptManager.cs
//
// Author:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C)2003 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Diagnostics;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace Mono.Xml.Xsl {
// FIXME: Correct evidence handling; test other than simple string case
internal class MSXslScriptManager {
Hashtable scripts = new Hashtable ();
public MSXslScriptManager () {}
public void AddScript (Compiler c)
{
MSXslScript s = new MSXslScript (c.Input, c.Evidence);
string ns = c.Input.GetNamespace (s.ImplementsPrefix);
if (ns == null)
throw new XsltCompileException ("Specified prefix for msxsl:script was not found: " + s.ImplementsPrefix, null, c.Input);
scripts.Add (ns, s.Compile (c.Input));
}
enum ScriptingLanguage {
JScript,
VisualBasic,
CSharp
}
public object GetExtensionObject (string ns)
{
if (!scripts.ContainsKey (ns))
return null;
return Activator.CreateInstance ((Type) scripts [ns]);
}
class MSXslScript {
ScriptingLanguage language = ScriptingLanguage.JScript; // default = JScript.
string implementsPrefix = null;
string code = null;
Evidence evidence;
public MSXslScript (XPathNavigator nav, Evidence evidence)
{
this.evidence = evidence;
code = nav.Value;
if (nav.MoveToFirstAttribute ()) {
do {
switch (nav.LocalName) {
case "language":
switch (nav.Value.ToLower (CultureInfo.InvariantCulture)) {
case "jscript":
case "javascript":
language = ScriptingLanguage.JScript; break;
case "vb":
case "visualbasic":
language = ScriptingLanguage.VisualBasic;
break;
case "c#":
case "csharp":
language = ScriptingLanguage.CSharp;
break;
default:
throw new XsltException ("Invalid scripting language!", null);
}
break;
case "implements-prefix":
implementsPrefix = nav.Value;
break;
}
} while (nav.MoveToNextAttribute ());
nav.MoveToParent ();
}
if (implementsPrefix == null)
throw new XsltException ("need implements-prefix attr", null);
}
public ScriptingLanguage Language {
get { return language; }
}
public string ImplementsPrefix {
get { return implementsPrefix; }
}
public string Code {
get { return code; }
}
public object Compile (XPathNavigator node)
{
#if TARGET_JVM || MOBILE
throw new NotImplementedException ();
#else
string suffix = "";
foreach (byte b in MD5.Create ().ComputeHash (Encoding.Unicode.GetBytes (code))) {
suffix += b.ToString ("x2");
}
switch (this.language) {
case ScriptingLanguage.CSharp:
return new CSharpCompilerInfo ().GetScriptClass (Code, suffix, node, evidence);
case ScriptingLanguage.JScript:
return new JScriptCompilerInfo ().GetScriptClass (Code, suffix, node, evidence);
case ScriptingLanguage.VisualBasic:
return new VBCompilerInfo ().GetScriptClass (Code, suffix, node, evidence);
default:
return null;
}
#endif
}
}
}
}

View File

@@ -0,0 +1,76 @@
//
// Outputter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
//
// (C) 2003 Oleg Tkachenko
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Xml;
namespace Mono.Xml.Xsl {
/// <summary>
/// Abstract XSLT outputter.
/// Transformation classes build result tree using only with this class API.
/// Implementations of this class outputs result tree to an Emitter, which emits
/// it further down to real consumers.
/// </summary>
internal abstract class Outputter {
public void WriteStartElement (string localName, string nsURI)
{
WriteStartElement (null, localName, nsURI);
}
public abstract void WriteStartElement (string prefix, string localName, string nsURI);
public abstract void WriteEndElement ();
public virtual void WriteFullEndElement ()
{
WriteEndElement ();
}
public void WriteAttributeString (string localName, string value)
{
WriteAttributeString ("", localName, "", value);
}
public abstract void WriteAttributeString (string prefix, string localName, string nsURI, string value);
public abstract void WriteNamespaceDecl (string prefix, string nsUri);
public abstract void WriteComment (string text);
public abstract void WriteProcessingInstruction (string name, string text);
public abstract void WriteString (string text);
public abstract void WriteRaw (string data);
public abstract void WriteWhitespace (string text);
public abstract void Done ();
public abstract bool CanProcessAttributes { get; }
public abstract bool InsideCDataSection { get; set; }
}
}

View File

@@ -0,0 +1,335 @@
//
// MSXslScriptManager.cs
//
// Author:
// Atsushi Enomoto (atsushi@ximian.com)
//
// (C)2003 Novell inc.
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security;
using System.Security.Policy;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
namespace Mono.Xml.Xsl
{
internal abstract class ScriptCompilerInfo
{
string compilerCommand;
string defaultCompilerOptions;
public virtual string CompilerCommand {
get { return compilerCommand; }
set { compilerCommand = value; }
}
public virtual string DefaultCompilerOptions {
get { return defaultCompilerOptions; }
set { defaultCompilerOptions = value; }
}
public abstract CodeDomProvider CodeDomProvider { get; }
public abstract string Extension { get; }
public abstract string SourceTemplate { get; }
public abstract string FormatSource (IXmlLineInfo li, string file, string code);
public virtual string GetCompilerArguments (string targetFileName)
{
return String.Concat (DefaultCompilerOptions, " ", targetFileName);
}
public virtual Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
{
PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
if (ps != null)
ps.Demand ();
// The attempt to use an already pre-compiled
// class assumes the caller has computed the
// classSuffix as a hash of the code
// string. MSXslScriptManager.cs does that.
// The mechanism how exactly such pre-compiled
// classes should be produced are not
// specified here.
string scriptname = "Script" + classSuffix;
string typename = "GeneratedAssembly." + scriptname;
try {
Type retval = Type.GetType (typename);
if (retval != null)
return retval;
} catch {
}
try {
Type retval = Assembly.LoadFrom (scriptname + ".dll").GetType (typename);
if (retval != null)
return retval;
} catch {
}
// OK, we have to actually compile the script.
ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
CompilerParameters parameters = new CompilerParameters ();
parameters.CompilerOptions = DefaultCompilerOptions;
// get source filename
string filename = String.Empty;
try {
if (scriptNode.BaseURI != String.Empty)
filename = new Uri (scriptNode.BaseURI).LocalPath;
} catch (FormatException) {
}
if (filename == String.Empty)
filename = "__baseURI_not_supplied__";
// get source location
IXmlLineInfo li = scriptNode as IXmlLineInfo;
string source = SourceTemplate.Replace ("{0}",
DateTime.Now.ToString (CultureInfo.InvariantCulture))
.Replace ("{1}", classSuffix)
.Replace ("{2}", code);
source = FormatSource (li, filename, source);
CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
foreach (CompilerError err in res.Errors)
if (!err.IsWarning)
// Actually it should be
// XsltCompileException, but to match
// with silly MS implementation...
// throw new XsltCompileException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
throw new XsltException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
if (res.CompiledAssembly == null)
throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
return res.CompiledAssembly.GetType (typename);
}
private string FormatErrorMessage (CompilerResults res)
{
string s = String.Empty;
foreach (CompilerError e in res.Errors) {
object [] parameters = new object [] {"\n",
e.FileName,
e.Line > 0 ? " line " + e.Line : String.Empty,
e.IsWarning ? " WARNING: " : " ERROR: ",
e.ErrorNumber,
": ",
e.ErrorText};
s += String.Concat (parameters);
}
return s;
}
}
internal class CSharpCompilerInfo : ScriptCompilerInfo
{
public CSharpCompilerInfo ()
{
this.CompilerCommand = "mcs";
#if MS_NET
this.CompilerCommand = "csc.exe";
#endif
this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll";
}
public override CodeDomProvider CodeDomProvider {
get { return new CSharpCodeProvider (); }
}
public override string Extension {
get { return ".cs"; }
}
public override string SourceTemplate {
get {
return @"// This file is automatically created by Mono managed XSLT engine.
// Created time: {0}
using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Microsoft.VisualBasic;
namespace GeneratedAssembly
{
public class Script{1}
{
{2}
}
}";
}
}
public override string FormatSource (IXmlLineInfo li, string file, string source)
{
if (li == null)
return source;
return String.Format (CultureInfo.InvariantCulture, "#line {0} \"{1}\"\n{2}", li.LineNumber, file, source);
}
}
internal class VBCompilerInfo : ScriptCompilerInfo
{
public VBCompilerInfo ()
{
this.CompilerCommand = "mbas";
this.DefaultCompilerOptions = "/t:library";
#if MS_NET
this.CompilerCommand = "vbc.exe";
this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
#endif
}
public override CodeDomProvider CodeDomProvider {
get { return new VBCodeProvider (); }
}
public override string Extension {
get { return ".vb"; }
}
public override string SourceTemplate {
get {
return @"' This file is automatically created by Mono managed XSLT engine.
' Created time: {0}
imports System
imports System.Collections
imports System.Text
imports System.Text.RegularExpressions
imports System.Xml
imports System.Xml.XPath
imports System.Xml.Xsl
imports Microsoft.VisualBasic
namespace GeneratedAssembly
public Class Script{1}
{2}
end Class
end namespace
";
}
}
public override string FormatSource (IXmlLineInfo li, string file, string source)
{
if (li == null)
return source;
return String.Format (CultureInfo.InvariantCulture,
"#ExternalSource (\"{1}\", {0})\n{2}\n#end ExternalSource",
li.LineNumber, new FileInfo (file).Name, source);
}
}
internal class JScriptCompilerInfo : ScriptCompilerInfo
{
static Type providerType;
public JScriptCompilerInfo ()
{
this.CompilerCommand = "mjs";
#if MS_NET
this.CompilerCommand = "jsc.exe";
#endif
this.DefaultCompilerOptions = "/t:library";
}
public override CodeDomProvider CodeDomProvider {
get {
// no need for locking
if (providerType == null) {
Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
if (jsasm != null)
providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
}
return (CodeDomProvider) Activator.CreateInstance (providerType);
}
}
public override string Extension {
get { return ".js"; }
}
public override string SourceTemplate {
get {
return @"// This file is automatically created by Mono managed XSLT engine.
// Created time: {0}
import System;
import System.Collections;
import System.Text;
import System.Text.RegularExpressions;
import System.Xml;
import System.Xml.XPath;
import System.Xml.Xsl;
import Microsoft.VisualBasic;
package GeneratedAssembly
{
class Script{1} {
{2}
}
}
";
}
}
public override string FormatSource (IXmlLineInfo li, string file, string source)
{
#if true // remove when mjs got @set @position support
return source;
#else
if (li == null)
return source;
return String.Format (CultureInfo.InvariantCulture,
"@set @position ({0}{1}{2}line={3};column={4})\n{5}",
file != null ? "file=" : String.Empty,
file,
file != null ? "; " : String.Empty,
li.LineNumber,
li.LinePosition,
source);
#endif
}
}
}

View File

@@ -0,0 +1,101 @@
//
// TextEmitter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
// Atsushi Enomoto (atsushi@ximian.com)
//
// (C) 2003 Oleg Tkachenko
// (C) 2004 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Text;
namespace Mono.Xml.Xsl
{
/// <summary>
/// Emitetr, which emits result tree according to "text" output method.
/// </summary>
internal class TextEmitter : Emitter
{
TextWriter writer;
public TextEmitter (TextWriter writer) {
this.writer = writer;
}
#region # Emitter's methods implementaion
public override void WriteStartDocument (Encoding encoding, StandaloneType standalone) {
//Do nothing
}
public override void WriteEndDocument () {
//Do nothing
}
public override void WriteDocType (string type, string publicId, string systemId) {
//Do nothing
}
public override void WriteStartElement (string prefix, string localName, string nsURI) {
//Do nothing
}
public override void WriteEndElement () {
//Do nothing
}
public override void WriteAttributeString (string prefix, string localName, string nsURI, string value) {
//Do nothing
}
public override void WriteComment (string text) {
//Do nothing
}
public override void WriteProcessingInstruction (string name, string text) {
//Do nothing
}
public override void WriteString (string text) {
writer.Write (text);
}
public override void WriteRaw (string data) {
writer.Write (data);
}
public override void WriteCDataSection (string text) {
writer.Write (text);
}
public override void Done () {
//Do nothing
}
#endregion
}
}

View File

@@ -0,0 +1,93 @@
//
// TextOutputter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
//
// (C) 2003 Oleg Tkachenko
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Xml;
using System.IO;
namespace Mono.Xml.Xsl {
/// <summary>
/// Outputter implementation for text output method.
/// </summary>
internal class TextOutputter : Outputter {
private TextWriter _writer;
//Current output depth
private int _depth;
//Ignore nested text nodes
private bool _ignoreNestedText;
public TextOutputter (TextWriter w, bool ignoreNestedText) {
_writer = w;
_ignoreNestedText = ignoreNestedText;
}
public override void WriteStartElement (string prefix, string localName, string nsURI) {
if (_ignoreNestedText) _depth++;
}
public override void WriteEndElement() {
if (_ignoreNestedText) _depth--;
}
public override void WriteAttributeString (string prefix, string localName, string nsURI, string value) {}
public override void WriteNamespaceDecl (string prefix, string nsUri) {}
public override void WriteComment (string text) {}
public override void WriteProcessingInstruction (string name, string text) {}
public override void WriteString (string text) {
WriteImpl (text);
}
public override void WriteRaw (string data) {
WriteImpl (data);
}
public override void WriteWhitespace (string text) {
WriteImpl (text);
}
private void WriteImpl(string text) {
if (!_ignoreNestedText || _depth==0) _writer.Write (text);
}
public override void Done () {
_writer.Flush ();
}
public override bool CanProcessAttributes {
get { return false; }
}
public override bool InsideCDataSection { get { return false; } set { } }
}
}

View File

@@ -0,0 +1,164 @@
//
// XmlWriterEmitter.cs
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
// Atsushi Enomoto (atsushi@ximian.com)
//
// (C) 2003 Oleg Tkachenko
// (C) 2004 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Text;
using System.Xml;
namespace Mono.Xml.Xsl
{
/// <summary>
/// Emitter, which emits result tree to a XmlWriter.
/// </summary>
internal class XmlWriterEmitter : Emitter
{
XmlWriter writer;
public XmlWriterEmitter (XmlWriter writer) {
this.writer = writer;
}
#region # Emitter's methods implementaion
public override void WriteStartDocument (Encoding encoding, StandaloneType standalone)
{
#if docent
if (standalone == StandaloneType.NONE)
writer.WriteStartDocument ();
else
writer.WriteStartDocument (standalone == StandaloneType.YES);
#else
string standaloneStr = "";
switch (standalone) {
case StandaloneType.YES:
standaloneStr = " standalone=\"yes\"";
break;
case StandaloneType.NO:
standaloneStr = " standalone=\"no\"";
break;
}
if (encoding == null)
writer.WriteProcessingInstruction ("xml", "version=\"1.0\"" + standaloneStr);
else
writer.WriteProcessingInstruction ("xml",
"version=\"1.0\" encoding=\""
+ encoding.WebName + "\""
+ standaloneStr);
#endif
}
public override void WriteEndDocument ()
{
#if docent
writer.WriteEndDocument ();
#endif
}
public override void WriteDocType (string type, string publicId, string systemId)
{
if (systemId == null) {
return;
}
writer.WriteDocType (type, publicId, systemId, null);
}
public override void WriteStartElement (string prefix, string localName, string nsURI)
{
writer.WriteStartElement (prefix, localName, nsURI);
}
public override void WriteEndElement ()
{
writer.WriteEndElement ();
}
public override void WriteFullEndElement ()
{
writer.WriteFullEndElement ();
}
public override void WriteAttributeString (string prefix, string localName, string nsURI, string value)
{
writer.WriteAttributeString (prefix, localName, nsURI, value);
}
public override void WriteComment (string text) {
//FIXME: horrible performance!!!
while (text.IndexOf ("--")>=0)
text = text.Replace ("--", "- -");
if ((text.EndsWith("-")))
text += ' ';
writer.WriteComment (text);
}
public override void WriteProcessingInstruction (string name, string text)
{
while (text.IndexOf ("?>") >= 0)
text = text.Replace ("?>", "? >");
writer.WriteProcessingInstruction (name, text);
}
public override void WriteString (string text)
{
writer.WriteString (text);
}
public override void WriteRaw (string data)
{
writer.WriteRaw (data);
}
public override void WriteCDataSection (string text)
{
int index = text.IndexOf ("]]>");
if (index >= 0) {
writer.WriteCData (text.Substring (0, index + 2));
WriteCDataSection (text.Substring (index + 2));
} else
writer.WriteCData (text);
}
public override void WriteWhitespace (string value)
{
writer.WriteWhitespace (value);
}
public override void Done ()
{
writer.Flush ();
}
#endregion
}
}

View File

@@ -0,0 +1,115 @@
//
// XslAttributeSet.cs
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) 2003 Ben Maurer
// (C) 2003 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using Mono.Xml.Xsl.Operations;
using QName = System.Xml.XmlQualifiedName;
namespace Mono.Xml.Xsl {
internal class XslAttributeSet : XslCompiledElement {
QName name;
// [QName]=>XslAttributeSet
ArrayList usedAttributeSets = new ArrayList ();
// [QName]=>XslAttribute
ArrayList attributes = new ArrayList ();
public XslAttributeSet (Compiler c) : base (c) {}
public QName Name {
get { return name; }
}
protected override void Compile (Compiler c)
{
this.name = c.ParseQNameAttribute ("name");
QName [] attrSets = c.ParseQNameListAttribute ("use-attribute-sets");
if (attrSets != null)
foreach (QName q in attrSets)
usedAttributeSets.Add (q);
if (!c.Input.MoveToFirstChild ()) return;
do {
if (c.Input.NodeType != XPathNodeType.Element)
continue;
if (c.Input.NamespaceURI != XsltNamespace || c.Input.LocalName != "attribute")
throw new XsltCompileException ("Invalid attr set content", null, c.Input);
attributes.Add (new XslAttribute (c));
} while (c.Input.MoveToNext ());
c.Input.MoveToParent ();
}
public void Merge (XslAttributeSet s)
{
attributes.AddRange (s.attributes);
foreach (QName q in s.usedAttributeSets)
if (!usedAttributeSets.Contains (q))
usedAttributeSets.Add (q);
}
public override void Evaluate (XslTransformProcessor p) {
p.SetBusy (this);
if (usedAttributeSets != null) {
for (int i = 0; i < usedAttributeSets.Count; i++) {
QName set = (QName) usedAttributeSets [i];
XslAttributeSet s = p.ResolveAttributeSet (set);
if (s == null)
throw new XsltException ("Could not resolve attribute set", null, p.CurrentNode);
if (p.IsBusy (s))
throw new XsltException ("circular dependency", null, p.CurrentNode);
s.Evaluate (p);
}
}
for (int i = 0; i < attributes.Count; i++)
((XslAttribute) attributes [i]).Evaluate (p);
p.SetFree (this);
}
}
}

View File

@@ -0,0 +1,339 @@
//
// XslDecimalFormat.cs
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
//
// (C) 2003 Ben Maurer
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Globalization;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using QName = System.Xml.XmlQualifiedName;
namespace Mono.Xml.Xsl {
internal class XslDecimalFormat {
NumberFormatInfo info = new NumberFormatInfo ();
char digit = '#', zeroDigit = '0', patternSeparator = ';';
string baseUri;
int lineNumber;
int linePosition;
public static readonly XslDecimalFormat Default = new XslDecimalFormat ();
XslDecimalFormat () {} // Default ctor for default info.
public XslDecimalFormat (Compiler c)
{
XPathNavigator n = c.Input;
IXmlLineInfo li = n as IXmlLineInfo;
if (li != null) {
lineNumber = li.LineNumber;
linePosition = li.LinePosition;
}
baseUri = n.BaseURI;
if (n.MoveToFirstAttribute ()) {
do {
if (n.NamespaceURI != String.Empty)
continue;
switch (n.LocalName) {
case "name": break; // already handled
case "decimal-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT decimal-separator value must be exact one character", null, n);
info.NumberDecimalSeparator = n.Value;
break;
case "grouping-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT grouping-separator value must be exact one character", null, n);
info.NumberGroupSeparator = n.Value;
break;
case "infinity":
info.PositiveInfinitySymbol = n.Value;
break;
case "minus-sign":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT minus-sign value must be exact one character", null, n);
info.NegativeSign = n.Value;
break;
case "NaN":
info.NaNSymbol = n.Value;
break;
case "percent":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT percent value must be exact one character", null, n);
info.PercentSymbol = n.Value;
break;
case "per-mille":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT per-mille value must be exact one character", null, n);
info.PerMilleSymbol = n.Value;
break;
case "digit":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT digit value must be exact one character", null, n);
digit = n.Value [0];
break;
case "zero-digit":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT zero-digit value must be exact one character", null, n);
zeroDigit = n.Value [0];
break;
case "pattern-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT pattern-separator value must be exact one character", null, n);
patternSeparator = n.Value [0];
break;
}
} while (n.MoveToNextAttribute ());
n.MoveToParent ();
info.NegativeInfinitySymbol = info.NegativeSign + info.PositiveInfinitySymbol;
}
}
public char Digit { get { return digit; } }
public char ZeroDigit { get { return zeroDigit; } }
public NumberFormatInfo Info { get { return info; } }
public char PatternSeparator { get { return patternSeparator; } }
public void CheckSameAs (XslDecimalFormat other)
{
if (this.digit != other.digit ||
this.patternSeparator != other.patternSeparator ||
this.zeroDigit != other.zeroDigit ||
this.info.NumberDecimalSeparator != other.info.NumberDecimalSeparator ||
this.info.NumberGroupSeparator != other.info.NumberGroupSeparator ||
this.info.PositiveInfinitySymbol != other.info.PositiveInfinitySymbol ||
this.info.NegativeSign != other.info.NegativeSign ||
this.info.NaNSymbol != other.info.NaNSymbol ||
this.info.PercentSymbol != other.info.PercentSymbol ||
this.info.PerMilleSymbol != other.info.PerMilleSymbol)
throw new XsltCompileException (null, other.baseUri, other.lineNumber, other.linePosition);
}
public string FormatNumber (double number, string pattern)
{
return ParsePatternSet (pattern).FormatNumber (number);
}
private DecimalFormatPatternSet ParsePatternSet (string pattern)
{
return new DecimalFormatPatternSet (pattern, this);
}
}
// set of positive pattern and negative pattern
internal class DecimalFormatPatternSet
{
DecimalFormatPattern positivePattern;
DecimalFormatPattern negativePattern;
// XslDecimalFormat decimalFormat;
public DecimalFormatPatternSet (string pattern, XslDecimalFormat decimalFormat)
{
Parse (pattern, decimalFormat);
}
private void Parse (string pattern, XslDecimalFormat format)
{
if (pattern.Length == 0)
throw new ArgumentException ("Invalid number format pattern string.");
positivePattern = new DecimalFormatPattern ();
negativePattern = positivePattern;
int pos = positivePattern.ParsePattern (0, pattern, format);
if (pos < pattern.Length) {
if (pattern [pos] != format.PatternSeparator)
// Expecting caught and wrapped by caller,
// since it cannot provide XPathNavigator.
// throw new ArgumentException ("Invalid number format pattern string.");
return;
pos++;
negativePattern = new DecimalFormatPattern ();
pos = negativePattern.ParsePattern (pos, pattern, format);
if (pos < pattern.Length)
throw new ArgumentException ("Number format pattern string ends with extraneous part.");
}
}
public string FormatNumber (double number)
{
if (number >= 0)
return positivePattern.FormatNumber (number);
else
return negativePattern.FormatNumber (number);
}
}
internal class DecimalFormatPattern
{
public string Prefix = String.Empty;
public string Suffix = String.Empty;
public string NumberPart;
NumberFormatInfo info;
StringBuilder builder = new StringBuilder ();
internal int ParsePattern (int start, string pattern, XslDecimalFormat format)
{
if (start == 0) // positive pattern
this.info = format.Info;
else {
this.info = format.Info.Clone () as NumberFormatInfo;
info.NegativeSign = String.Empty; // should be specified in Prefix
}
// prefix
int pos = start;
while (pos < pattern.Length) {
if (pattern [pos] == format.ZeroDigit || pattern [pos] == format.Digit || pattern [pos] == format.Info.CurrencySymbol [0])
break;
else
pos++;
}
Prefix = pattern.Substring (start, pos - start);
if (pos == pattern.Length) {
// Invalid number pattern.
// throw new ArgumentException ("Invalid number format pattern.");
return pos;
}
// number
pos = ParseNumber (pos, pattern, format);
int suffixStart = pos;
// suffix
while (pos < pattern.Length) {
if (pattern [pos] == format.ZeroDigit || pattern [pos] == format.Digit || pattern [pos] == format.PatternSeparator || pattern [pos] == format.Info.CurrencySymbol [0])
break;
else
pos++;
}
Suffix = pattern.Substring (suffixStart, pos - suffixStart);
return pos;
}
// FIXME: Collect grouping digits
private int ParseNumber (int start, string pattern, XslDecimalFormat format)
{
int pos = start;
// process non-minint part.
for (; pos < pattern.Length; pos++) {
if (pattern [pos] == format.Digit)
builder.Append ('#');
else if (pattern [pos] == format.Info.NumberGroupSeparator [0])
builder.Append (',');
else
break;
}
// minint part.
for (; pos < pattern.Length; pos++) {
if (pattern [pos] == format.ZeroDigit)
builder.Append ('0');
else if (pattern [pos] == format.Info.NumberGroupSeparator [0])
builder.Append (',');
else
break;
}
// optional fraction part
if (pos < pattern.Length) {
if (pattern [pos] == format.Info.NumberDecimalSeparator [0]) {
builder.Append ('.');
pos++;
}
while (pos < pattern.Length) {
if (pattern [pos] == format.ZeroDigit) {
pos++;
builder.Append ('0');
}
else
break;
}
while (pos < pattern.Length) {
if (pattern [pos] == format.Digit) {
pos++;
builder.Append ('#');
}
else
break;
}
}
// optional exponent part
if (pos + 1 < pattern.Length && pattern [pos] == 'E' && pattern [pos + 1] == format.ZeroDigit) {
pos += 2;
builder.Append ("E0");
while (pos < pattern.Length) {
if (pattern [pos] == format.ZeroDigit) {
pos++;
builder.Append ('0');
}
else
break;
}
}
// misc special characters
if (pos < pattern.Length) {
if (pattern [pos] == this.info.PercentSymbol [0])
builder.Append ('%');
else if (pattern [pos] == this.info.PerMilleSymbol [0])
builder.Append ('\u2030');
else if (pattern [pos] == this.info.CurrencySymbol [0])
throw new ArgumentException ("Currency symbol is not supported for number format pattern string.");
else
pos--;
pos++;
}
NumberPart = builder.ToString ();
return pos;
}
public string FormatNumber (double number)
{
builder.Length = 0;
builder.Append (Prefix);
builder.Append (number.ToString (NumberPart, info));
builder.Append (Suffix);
return builder.ToString ();
}
}
}

View File

@@ -0,0 +1,155 @@
//
// XslDecimalFormat.jvm.cs
//
// Authors:
// Andrew Skiba <andrews@mainsoft.com>
//
// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using QName = System.Xml.XmlQualifiedName;
namespace Mono.Xml.Xsl {
internal class XslDecimalFormat {
java.text.DecimalFormatSymbols javaFormat;
string baseUri;
int lineNumber;
int linePosition;
public static readonly XslDecimalFormat Default = new XslDecimalFormat ();
XslDecimalFormat ()
{
javaFormat = new java.text.DecimalFormatSymbols ();
javaFormat.setNaN ("NaN");
javaFormat.setInfinity ("Infinity");
}
public XslDecimalFormat (Compiler c)
:this ()
{
Initialize(c);
}
private void Initialize(Compiler c)
{
XPathNavigator n = c.Input;
IXmlLineInfo li = n as IXmlLineInfo;
if (li != null) {
lineNumber = li.LineNumber;
linePosition = li.LinePosition;
}
baseUri = n.BaseURI;
if (n.MoveToFirstAttribute ()) {
do {
if (n.NamespaceURI != String.Empty)
continue;
switch (n.LocalName) {
case "name": break; // already handled
case "decimal-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT decimal-separator value must be exact one character.", null, n);
javaFormat.setDecimalSeparator (n.Value[0]);
break;
case "grouping-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT grouping-separator value must be exact one character.", null, n);
javaFormat.setGroupingSeparator (n.Value[0]);
break;
case "infinity":
javaFormat.setInfinity (n.Value);
break;
case "minus-sign":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT minus-sign value must be exact one character.", null, n);
javaFormat.setMinusSign (n.Value[0]);
break;
case "NaN":
javaFormat.setNaN (n.Value);
break;
case "percent":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT percent value must be exact one character.", null, n);
javaFormat.setPercent (n.Value[0]);
break;
case "per-mille":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT per-mille value must be exact one character.", null, n);
javaFormat.setPerMill (n.Value[0]);
break;
case "digit":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT digit value must be exact one character.", null, n);
javaFormat.setDigit (n.Value[0]);
break;
case "zero-digit":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT zero-digit value must be exact one character.", null, n);
javaFormat.setZeroDigit (n.Value [0]);
break;
case "pattern-separator":
if (n.Value.Length != 1)
throw new XsltCompileException ("XSLT pattern-separator value must be exact one character.", null, n);
javaFormat.setPatternSeparator (n.Value [0]);
break;
}
} while (n.MoveToNextAttribute ());
n.MoveToParent ();
}
}
public void CheckSameAs (XslDecimalFormat other)
{
if (! this.javaFormat.Equals (other.javaFormat))
throw new XsltCompileException (null, other.baseUri, other.lineNumber, other.linePosition);
}
public string FormatNumber (double number, string pattern)
{
java.text.DecimalFormat frm = new java.text.DecimalFormat("", javaFormat);
frm.applyLocalizedPattern (pattern);
//TODO: the next 4 string could be replaced by just
//return frm.format (number);
//I don't want to do that before release
java.lang.StringBuffer buffer= new java.lang.StringBuffer ();
java.text.FieldPosition fld = new java.text.FieldPosition (0);
frm.format (number, buffer, fld);
return buffer.ToString();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,279 @@
//
// XslKey.cs
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) 2003 Ben Maurer
// (C) 2003 Atsushi Enomoto
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using Mono.Xml.XPath;
using QName = System.Xml.XmlQualifiedName;
namespace Mono.Xml.Xsl
{
internal class ExprKeyContainer : Expression
{
Expression expr;
public ExprKeyContainer (Expression expr)
{
this.expr = expr;
}
public Expression BodyExpression {
get { return expr; }
}
public override object Evaluate (BaseIterator iter)
{
return expr.Evaluate (iter);
}
internal override XPathNodeType EvaluatedNodeType {
get { return expr.EvaluatedNodeType; }
}
public override XPathResultType ReturnType {
get { return expr.ReturnType; }
}
}
internal class XslKey
{
QName name;
CompiledExpression useExpr;
Pattern matchPattern;
public XslKey (Compiler c)
{
this.name = c.ParseQNameAttribute ("name");
c.KeyCompilationMode = true;
useExpr = c.CompileExpression (c.GetAttribute ("use"));
if (useExpr == null)
useExpr = c.CompileExpression (".");
c.AssertAttribute ("match");
string matchString = c.GetAttribute ("match");
this.matchPattern = c.CompilePattern (matchString, c.Input);
c.KeyCompilationMode = false;
}
public QName Name { get { return name; }}
internal CompiledExpression Use { get { return useExpr; }}
internal Pattern Match { get { return matchPattern; }}
}
// represents part of dynamic context that holds index table for a key
internal class KeyIndexTable
{
// XsltCompiledContext ctx;
ArrayList keys;
Hashtable mappedDocuments;
public KeyIndexTable (XsltCompiledContext ctx, ArrayList keys)
{
// this.ctx = ctx;
this.keys = keys;
}
public ArrayList Keys {
get { return keys; }
}
private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map)
{
for (int i = 0; i < keys.Count; i++)
CollectTable (doc, ctx, map, (XslKey) keys[i]);
}
private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map, XslKey key)
{
XPathNavigator nav = doc.Clone ();
nav.MoveToRoot ();
XPathNavigator tmp = doc.Clone ();
bool matchesAttributes = false;
switch (key.Match.EvaluatedNodeType) {
case XPathNodeType.All:
case XPathNodeType.Attribute:
matchesAttributes = true;
break;
}
do {
if (key.Match.Matches (nav, ctx)) {
tmp.MoveTo (nav);
CollectIndex (nav, tmp, map);
}
} while (MoveNavigatorToNext (nav, matchesAttributes));
if (map != null)
foreach (ArrayList list in map.Values)
list.Sort (XPathNavigatorComparer.Instance);
}
private bool MoveNavigatorToNext (XPathNavigator nav, bool matchesAttributes)
{
if (matchesAttributes) {
if (nav.NodeType != XPathNodeType.Attribute &&
nav.MoveToFirstAttribute ())
return true;
else if (nav.NodeType == XPathNodeType.Attribute) {
if (nav.MoveToNextAttribute ())
return true;
nav.MoveToParent ();
}
}
if (nav.MoveToFirstChild ())
return true;
do {
if (nav.MoveToNext ())
return true;
} while (nav.MoveToParent ());
return false;
}
private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map)
{
for (int i = 0; i < keys.Count; i++)
CollectIndex (nav, target, map, (XslKey) keys[i]);
}
private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map, XslKey key)
{
XPathNodeIterator iter;
switch (key.Use.ReturnType) {
case XPathResultType.NodeSet:
iter = nav.Select (key.Use);
while (iter.MoveNext ())
AddIndex (iter.Current.Value, target, map);
break;
case XPathResultType.Any:
object o = nav.Evaluate (key.Use);
iter = o as XPathNodeIterator;
if (iter != null) {
while (iter.MoveNext ())
AddIndex (iter.Current.Value, target, map);
}
else
AddIndex (XPathFunctions.ToString (o), target, map);
break;
default:
string keyValue = nav.EvaluateString (key.Use, null, null);
AddIndex (keyValue, target, map);
break;
}
}
private void AddIndex (string key, XPathNavigator target, Hashtable map)
{
ArrayList al = map [key] as ArrayList;
if (al == null) {
al = new ArrayList ();
map [key] = al;
}
for (int i = 0; i < al.Count; i++)
if (((XPathNavigator) al [i]).IsSamePosition (target))
return;
al.Add (target.Clone ());
}
private ArrayList GetNodesByValue (XPathNavigator nav, string value, XsltContext ctx)
{
if (mappedDocuments == null)
mappedDocuments = new Hashtable ();
Hashtable map = (Hashtable) mappedDocuments [nav.BaseURI];
if (map == null) {
map = new Hashtable ();
mappedDocuments.Add (nav.BaseURI, map);
CollectTable (nav, ctx, map);
}
return map [value] as ArrayList;
}
public bool Matches (XPathNavigator nav, string value, XsltContext ctx)
{
ArrayList al = GetNodesByValue (nav, value, ctx);
if (al == null)
return false;
for (int i = 0; i < al.Count; i++)
if (((XPathNavigator) al [i]).IsSamePosition (nav))
return true;
return false;
}
// Invoked from XsltKey (XPathFunction)
public BaseIterator Evaluate (BaseIterator iter,
Expression valueExpr)
{
XPathNodeIterator i = iter;
if (iter.CurrentPosition == 0) {
i = iter.Clone ();
i.MoveNext ();
}
XPathNavigator nav = i.Current;
object o = valueExpr.Evaluate (iter);
XPathNodeIterator it = o as XPathNodeIterator;
XsltContext ctx = iter.NamespaceManager as XsltContext;
BaseIterator result = null;
if (it != null) {
while (it.MoveNext()) {
ArrayList nodes = GetNodesByValue (
nav, it.Current.Value, ctx);
if (nodes == null)
continue;
ListIterator tmp =
new ListIterator (nodes, ctx);
if (result == null)
result = tmp;
else
result = new UnionIterator (
iter, result, tmp);
}
}
else if (nav != null) {
ArrayList nodes = GetNodesByValue (
nav, XPathFunctions.ToString (o), ctx);
if (nodes != null)
result = new ListIterator (nodes, ctx);
}
return result != null ? result : new NullIterator (iter);
}
}
}

View File

@@ -0,0 +1,294 @@
//
// XslOutput.cs
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
// Oleg Tkachenko (oleg@tkachenko.com)
//
// (C) 2003 Ben Maurer
// (C) 2003 Atsushi Enomoto
// (C) 2003 Oleg Tkachenko
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Text;
namespace Mono.Xml.Xsl
{
using QName = System.Xml.XmlQualifiedName;
internal enum OutputMethod {
XML,
HTML,
Text,
Custom,
Unknown
}
internal enum StandaloneType {
NONE,
YES,
NO
}
internal class XslOutput // also usable for xsl:result-document
{
string uri;
QName customMethod;
OutputMethod method = OutputMethod.Unknown;
string version;
Encoding encoding = System.Text.Encoding.UTF8;
bool omitXmlDeclaration;
StandaloneType standalone = StandaloneType.NONE;
string doctypePublic;
string doctypeSystem;
QName [] cdataSectionElements;
string indent;
string mediaType;
string stylesheetVersion;
// for compilation only.
ArrayList cdSectsList = new ArrayList ();
public XslOutput (string uri, string stylesheetVersion)
{
this.uri = uri;
this.stylesheetVersion = stylesheetVersion;
}
public OutputMethod Method { get { return method; }}
public QName CustomMethod { get { return customMethod; }}
public string Version {
get { return version; }
}
public Encoding Encoding {
get { return encoding; }
}
public string Uri {
get { return uri; }
}
public bool OmitXmlDeclaration {
get { return omitXmlDeclaration; }
}
public StandaloneType Standalone {
get { return standalone; }
}
public string DoctypePublic {
get { return doctypePublic; }
}
public string DoctypeSystem {
get { return doctypeSystem; }
}
public QName [] CDataSectionElements {
get {
if (cdataSectionElements == null)
cdataSectionElements = cdSectsList.ToArray (typeof (QName)) as QName [];
return cdataSectionElements;
}
}
public string Indent {
get { return indent; }
}
public string MediaType {
get { return mediaType; }
}
public void Fill (XPathNavigator nav)
{
if (nav.MoveToFirstAttribute ()) {
ProcessAttribute (nav);
while (nav.MoveToNextAttribute ()) {
ProcessAttribute (nav);
}
// move back to original position
nav.MoveToParent ();
}
}
private void ProcessAttribute (XPathNavigator nav)
{
// skip attributes from non-default namespace
if (nav.NamespaceURI != string.Empty) {
return;
}
string value = nav.Value;
switch (nav.LocalName) {
case "cdata-section-elements":
if (value.Length > 0) {
cdSectsList.AddRange (XslNameUtil.FromListString (value, nav));
}
break;
case "method":
if (value.Length == 0) {
break;
}
switch (value) {
case "xml":
method = OutputMethod.XML;
break;
case "html":
omitXmlDeclaration = true;
method = OutputMethod.HTML;
break;
case "text":
omitXmlDeclaration = true;
method = OutputMethod.Text;
break;
default:
method = OutputMethod.Custom;
customMethod = XslNameUtil.FromString (value, nav);
if (customMethod.Namespace == String.Empty) {
IXmlLineInfo li = nav as IXmlLineInfo;
throw new XsltCompileException (new ArgumentException (
"Invalid output method value: '" + value + "'. It" +
" must be either 'xml' or 'html' or 'text' or QName."),
nav.BaseURI,
li != null ? li.LineNumber : 0,
li != null ? li.LinePosition : 0);
}
break;
}
break;
case "version":
if (value.Length > 0) {
this.version = value;
}
break;
case "encoding":
if (value.Length > 0) {
try {
this.encoding = System.Text.Encoding.GetEncoding (value);
} catch (ArgumentException) {
// MS.NET just leaves the default encoding when encoding is unknown
} catch (NotSupportedException) {
// Workaround for a bug in System.Text, it throws invalid exception
}
}
break;
case "standalone":
switch (value) {
case "yes":
this.standalone = StandaloneType.YES;
break;
case "no":
this.standalone = StandaloneType.NO;
break;
default:
if (stylesheetVersion != "1.0")
break;
IXmlLineInfo li = nav as IXmlLineInfo;
throw new XsltCompileException (new XsltException (
"'" + value + "' is an invalid value for 'standalone'" +
" attribute.", (Exception) null),
nav.BaseURI,
li != null ? li.LineNumber : 0,
li != null ? li.LinePosition : 0);
}
break;
case "doctype-public":
this.doctypePublic = value;
break;
case "doctype-system":
this.doctypeSystem = value;
break;
case "media-type":
if (value.Length > 0) {
this.mediaType = value;
}
break;
case "omit-xml-declaration":
switch (value) {
case "yes":
this.omitXmlDeclaration = true;
break;
case "no":
this.omitXmlDeclaration = false;
break;
default:
if (stylesheetVersion != "1.0")
break;
IXmlLineInfo li = nav as IXmlLineInfo;
throw new XsltCompileException (new XsltException (
"'" + value + "' is an invalid value for 'omit-xml-declaration'" +
" attribute.", (Exception) null),
nav.BaseURI,
li != null ? li.LineNumber : 0,
li != null ? li.LinePosition : 0);
}
break;
case "indent":
indent = value;
if (stylesheetVersion != "1.0")
break;
switch (value) {
case "yes":
case "no":
break;
default:
switch (method) {
case OutputMethod.Custom:
break;
default:
throw new XsltCompileException (String.Format ("Unexpected 'indent' attribute value in 'output' element: '{0}'", value), null, nav);
}
break;
}
break;
default:
if (stylesheetVersion != "1.0")
break;
IXmlLineInfo xli = nav as IXmlLineInfo;
throw new XsltCompileException (new XsltException (
"'" + nav.LocalName + "' is an invalid attribute for 'output'" +
" element.", (Exception) null),
nav.BaseURI,
xli != null ? xli.LineNumber : 0,
xli != null ? xli.LinePosition : 0);
}
}
}
}

View File

@@ -0,0 +1,97 @@
//
// XslSortEvaluator.cs
//
// Author:
// Atsushi Enomoto (atsushi@ximian.com)
//
// Copyright (C) 2006 Novell, Inc. http://www.novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//
// This class handles xsl:sort to have XslTransformProcessor involved in
// the evaluation of resulting nodeset. Beyond XPathExpression.AddSort(),
// it handles current() by having .
//
using System;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
namespace Mono.Xml.Xsl
{
class XslSortEvaluator
{
public XslSortEvaluator (XPathExpression select, Sort [] sorterTemplates)
{
this.select = select;
this.sorterTemplates = sorterTemplates;
PopulateConstantSorters ();
sortRunner = new XPathSorters ();
}
XPathExpression select;
Sort [] sorterTemplates;
XPathSorter [] sorters;
XPathSorters sortRunner;
bool isSorterContextDependent;
void PopulateConstantSorters ()
{
sorters = new XPathSorter [sorterTemplates.Length];
for (int i = 0; i < sorterTemplates.Length; i++) {
Sort sort = sorterTemplates [i];
if (sort.IsContextDependent)
isSorterContextDependent = true;
else
sorters [i] = sort.ToXPathSorter (null);
}
}
public BaseIterator SortedSelect (XslTransformProcessor p)
{
if (isSorterContextDependent) {
for (int i = 0; i < sorters.Length; i++)
if (sorterTemplates [i].IsContextDependent)
sorters [i] = sorterTemplates [i].ToXPathSorter (p);
}
BaseIterator iter = (BaseIterator) p.Select (select);
p.PushNodeset (iter);
p.PushForEachContext ();
ArrayList list = new ArrayList (iter.Count);
while (iter.MoveNext ()) {
XPathSortElement item = new XPathSortElement ();
item.Navigator = iter.Current.Clone ();
item.Values = new object [sorters.Length];
for (int i = 0; i < sorters.Length; i++)
item.Values [i] = sorters [i].Evaluate (iter);
list.Add (item);
}
p.PopForEachContext ();
p.PopNodeset ();
sortRunner.CopyFrom (sorters);
return sortRunner.Sort (list, iter.NamespaceManager);
}
}
}

Some files were not shown because too many files have changed in this diff Show More