* Compiler.cs : Modified decimal-format comparison code.
* Outputter.cs,
TextOutputter.cs,
GenericOutputter.cs : Added WriteState. Now WriteStartDocument() will
be called only when required.
* HtmlEmitter.cs : Improved indentation stuff.
* XslDecimalFormat.cs : Added incomplete implementation of
CheckSameAs() and FormatNumber().
* XslStylesheet.cs,
XslTransformProcessor.cs : Changed XslStylesheet.StylesheetNamespaces
from StringDictionary to ArrayList of QName (to keep order).
svn path=/trunk/mcs/; revision=20323
+2003-11-21 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+ * Compiler.cs : Modified decimal-format comparison code.
+ * Outputter.cs,
+ TextOutputter.cs,
+ GenericOutputter.cs : Added WriteState. Now WriteStartDocument() will
+ be called only when required.
+ * HtmlEmitter.cs : Improved indentation stuff.
+ * XslDecimalFormat.cs : Added incomplete implementation of
+ CheckSameAs() and FormatNumber().
+ * XslStylesheet.cs,
+ XslTransformProcessor.cs : Changed XslStylesheet.StylesheetNamespaces
+ from StringDictionary to ArrayList of QName (to keep order).
+
2003-11-19 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
* XsltCompiledContext.cs : XsltGenerateId.Evaluate() should consider
public void CompileDecimalFormat ()
{
QName nm = ParseQNameAttribute ("name");
+ XslDecimalFormat df = new XslDecimalFormat (this);
if (decimalFormats.Contains (nm))
- ((XslDecimalFormat)decimalFormats [nm]).CheckSameAs (this);
+ ((XslDecimalFormat)decimalFormats [nm]).CheckSameAs (df);
else
- decimalFormats [nm] = new XslDecimalFormat (this);
+ decimalFormats [nm] = df;
}
#endregion
#region Static XSLT context
switch (xslOutput.Method) {
case OutputMethod.HTML:
- Console.WriteLine ("WARNING: HTML output not fully supported, using XML output");
_emitter = new HtmlEmitter (writer, xslOutput);
break;
case OutputMethod.Unknown: //TODO: handle xml vs html
case OutputMethod.XML:
- //TODO: XmlTextEmitter goes here
- //_emitter = new XmlTextEmitter (writer);
XmlTextWriter w = new XmlTextWriter (writer);
if (xslOutput.Indent == "yes")
w.Formatting = Formatting.Indented;
/// when it's appropriate.
/// </summary>
private void CheckState ()
- {
+ {
+ if (_state == WriteState.Start)
+ WriteStartDocument ();
+
if (_state == WriteState.Element) {
//Push scope to allow to unwind namespaces scope back in WriteEndElement
//Subject to optimization - avoid redundant push/pop by moving
int _nsCount;
public override void WriteStartElement (string prefix, string localName, string nsURI)
{
+ if (_state == WriteState.Start)
+ WriteStartDocument ();
+
if (_state == WriteState.Prolog) {
//Seems to be the first element - take care of Doctype
if (_currentOutput.DoctypeSystem != null)
public override bool CanProcessAttributes {
get { return canProcessAttributes; }
}
+
+ public override WriteState WriteState { get { return _state; } }
#endregion
}
}
openElement = false;
}
+ // FIXME: check all HTML elements' indentation.
private void Indent (string elementName, bool alwaysOutputNewLine)
{
if (!indent)
return;
switch (elementName.ToUpper ()) {
- case "FORM":
- return;
+ case "ADDRESS":
+ case "BDO":
+ case "BLOCKQUOTE":
+ case "BODY":
+ case "BUTTON":
+ case "CAPTION":
+ case "CENTER":
+ case "DD":
+ case "DEL":
+ case "DIR":
+ case "DIV":
+ case "DL":
+ case "DT":
+ case "FIELDSET":
+ case "H1":
+ case "H2":
+ case "H3":
+ case "H4":
+ case "H5":
+ case "H6":
+ case "HEAD":
+ case "HTML":
+ case "IFRAME":
+ case "INS":
+ case "LI":
+ case "MAP":
+ case "MENU":
+ case "NOFRAMES":
+ case "NOSCRIPT":
+ case "OBJECT":
+ case "P":
+ case "PRE":
+ case "TD":
+ case "TH":
+ if (alwaysOutputNewLine || elementNameStack.Count > 0)
+ writer.Write ("\r\n");
+ for (int i = 0; i < elementNameStack.Count; i++)
+ writer.Write (" ");
+ break;
}
- if (alwaysOutputNewLine || elementNameStack.Count > 0)
- writer.Write ("\r\n");
- for (int i = 0; i < elementNameStack.Count; i++)
- writer.Write (" ");
}
public override void WriteStartElement (string prefix, string localName, string nsURI)
//
using System;
+using System.Xml;
namespace Mono.Xml.Xsl {
/// <summary>
public virtual bool CanProcessAttributes {
get { return false; }
}
+
+ public abstract WriteState WriteState { get; }
}
}
public override void Done () {
_writer.Flush ();
}
+
+ public override WriteState WriteState { get { return WriteState.Start; } }
}
}
NumberFormatInfo info = new NumberFormatInfo ();
char digit = '#', zeroDigit = '0', patternSeparator = ';';
+ XPathNavigator source;
+ string baseUri;
+ int lineNumber;
+ int linePosition;
public static readonly XslDecimalFormat Default = new XslDecimalFormat ();
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 != Compiler.XsltNamespace)
+ if (n.NamespaceURI != String.Empty)
continue;
switch (n.LocalName) {
case "per-mille":
info.PerMilleSymbol = n.Value;
break;
- case "zero-digit":
+ case "digit":
digit = n.Value [0];
break;
- case "digit":
+ case "zero-digit":
zeroDigit = n.Value [0];
break;
case "pattern-separator":
info.NegativeInfinitySymbol = info.NegativeSign + info.PositiveInfinitySymbol;
}
}
-
- // check that the data in c is the same as this one, as we
- // must do, per the spec.
- public void CheckSameAs (Compiler c)
+
+ // TODO: complete comparison for XSLT spec. 12.3.
+ public void CheckSameAs (XslDecimalFormat other)
{
- throw new NotImplementedException ();
+ if (this.digit != other.digit ||
+ this.patternSeparator != other.patternSeparator ||
+ this.zeroDigit != other.zeroDigit)
+ throw new XsltCompileException (null, other.baseUri, other.lineNumber, other.linePosition);
}
+ // TODO: format pattern check.
public string FormatNumber (double number, string pattern)
{
- throw new NotImplementedException ();
+ return number.ToString (pattern, info);
}
}
}
\ No newline at end of file
string version;
XmlQualifiedName [] extensionElementPrefixes;
XmlQualifiedName [] excludeResultPrefixes;
- StringDictionary stylesheetNamespaces = new StringDictionary ();
+ ArrayList stylesheetNamespaces = new ArrayList ();
// below are newly introduced in XSLT 2.0
// elements::
get { return excludeResultPrefixes; }
}
- public StringDictionary StylesheetNamespaces {
+ public ArrayList StylesheetNamespaces {
get { return stylesheetNamespaces; }
}
do {
if (c.Input.Value == XsltNamespace)
continue;
- this.stylesheetNamespaces.Add (c.Input.Name, c.Input.Value);
+ this.stylesheetNamespaces.Insert (0, new QName (c.Input.Name, c.Input.Value));
} while (c.Input.MoveToNextNamespace (XPathNamespaceScope.Local));
c.Input.MoveToParent ();
}
internal void TryStylesheetNamespaceOutput ()
{
if (outputStylesheetXmlns) {
- foreach (string prefix in this.style.StylesheetNamespaces.Keys) {
+ foreach (XmlQualifiedName qname in this.style.StylesheetNamespaces) {
+ string prefix = qname.Name;
if (style.ExcludeResultPrefixes != null) {
bool exclude = false;
foreach (XmlQualifiedName exc in style.ExcludeResultPrefixes)
if (exclude)
continue;
}
- Out.WriteNamespaceDecl (prefix, this.style.StylesheetNamespaces [prefix]);
+ Out.WriteNamespaceDecl (prefix, qname.Namespace);
}
outputStylesheetXmlns = false;
}