+2003-11-02 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+ * Compiler.cs : More complete attribute set gathering.
+ GetNamespacesToCopy() should only return Local namespaces.
+ * GenericOutputter.cs : Added support for indentation.
+ Added easy hack for html output.
+ More correct Prefix handling (considers already defined ones).
+ Namespace emmission is moved to CheckState().
+ * Emitter.cs, XmlWriterEmitter.cs, GenericOutputter.cs, Outputter.cs :
+ Added WriteFullEndElement(). (i.e. IsEmptyElement support)
+ * GenericOutputter.cs, Outputter.cs :
+ Added CanProcessAttributes property for
+ use-attribute-sets of xsl:copy.
+ * XslStylesheet.cs : Added support for stylesheet-defined xmlns decls.
+ Added support for exclude-result-prefixes.
+ * XslTransformProcessor.cs : Added support for stylesheet-defined xmlns.
+
2003-10-30 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
* Compiler.cs : It is not important, but attribute order became closer
//
// Authors:
// Oleg Tkachenko (oleg@tkachenko.com)
+// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
-// (C) 2003 Oleg Tkachenko
+// (C) 2003 Oleg Tkachenko, Atsushi Enomoto
//
using System;
int pendingAttributesPos = 0;
//Namespace manager. Subject to optimization.
private XmlNamespaceManager _nsManager;
+ private ArrayList _currentNsPrefixes;
+ private Hashtable _currentNamespaceDecls;
//Name table
private NameTable _nt;
-
+ //Determines whether xsl:copy can output attribute-sets or not.
+ bool canProcessAttributes;
+ // FIXME: This is quick hack to eliminate XML declaration for HTML output.
+ bool htmlEmulation;
+
private GenericOutputter (Hashtable outputs)
{
_outputs = outputs;
//TODO: Optimize using nametable
_nt = new NameTable ();
_nsManager = new XmlNamespaceManager (_nt);
+ _currentNsPrefixes = new ArrayList ();
+ _currentNamespaceDecls = new Hashtable ();
}
public GenericOutputter (XmlWriter writer, Hashtable outputs)
case OutputMethod.HTML:
Console.WriteLine ("WARNING: HTML output not fully supported, using XML output");
+ htmlEmulation = true;
goto case OutputMethod.XML;
case OutputMethod.Unknown: //TODO: handle xml vs html
case OutputMethod.XML:
//TODO: XmlTextEmitter goes here
//_emitter = new XmlTextEmitter (writer);
- _emitter = new XmlWriterEmitter (new XmlTextWriter (writer));
+ XmlTextWriter w = new XmlTextWriter (writer);
+ if (_currentOutput.Indent)
+ w.Formatting = Formatting.Indented;
+ if (htmlEmulation)
+ w.Formatting = Formatting.Indented;
+ _emitter = new XmlWriterEmitter (w);
break;
case OutputMethod.Text:
_emitter = new TextEmitter (writer);
//Emit pending attributes
for (int i = 0; i < pendingAttributesPos; i++) {
Attribute attr = pendingAttributes [i];
- _emitter.WriteAttributeString (attr.Prefix, attr.LocalName, attr.Namespace, attr.Value);
- }
+ string prefix = _nsManager.LookupPrefix (attr.Namespace);
+ if (prefix == null)
+ prefix = attr.Prefix;
+ _emitter.WriteAttributeString (prefix, attr.LocalName, attr.Namespace, attr.Value);
+ }
+ foreach (string prefix in _currentNsPrefixes) {
+ 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);
+ }
+ _currentNsPrefixes.Clear ();
+ _currentNamespaceDecls.Clear ();
//Attributes flushed, state is Content now
_state = WriteState.Content;
- }
+ }
+ canProcessAttributes = false;
}
#region Outputter's methods implementation
public override void WriteStartDocument ()
{
- if (!_currentOutput.OmitXmlDeclaration)
+ if (!_currentOutput.OmitXmlDeclaration && !htmlEmulation)
_emitter.WriteStartDocument (_currentOutput.Standalone);
_state = WriteState.Prolog;
_emitter.WriteStartElement (prefix, localName, nsURI);
_state = WriteState.Element;
pendingAttributesPos = 0;
+ canProcessAttributes = true;
}
public override void WriteEndElement ()
+ {
+ WriteEndElementInternal (false);
+ }
+
+ public override void WriteFullEndElement()
+ {
+ WriteEndElementInternal (true);
+ }
+
+ private void WriteEndElementInternal (bool fullEndElement)
{
CheckState ();
- _emitter.WriteEndElement ();
+ if (fullEndElement)
+ _emitter.WriteFullEndElement ();
+ else
+ _emitter.WriteEndElement ();
_state = WriteState.Content;
//Pop namespace scope
_nsManager.PopScope ();
//Keep prefix (e.g. when literal attribute is overriden by xsl:attribute)
if (attr.Prefix == String.Empty && prefix != String.Empty)
pendingAttributes [i].Prefix = prefix;
-
return;
}
}
{
if (prefix == String.Empty) {
//Default namespace
- if (_nsManager.DefaultNamespace != nsUri) {
+ if (_nsManager.DefaultNamespace != nsUri)
_nsManager.AddNamespace (prefix, nsUri);
- _emitter.WriteAttributeString ("", "xmlns", "", nsUri);
- }
- } else if (_nsManager.LookupPrefix (nsUri) == null) {
- //That's new namespace - add it to the collection and emit
+ } else if (_nsManager.LookupPrefix (nsUri) == null)
+ //That's new namespace - add it to the collection
_nsManager.AddNamespace (prefix, nsUri);
- _emitter.WriteAttributeString ("xmlns", prefix, null, nsUri);
- }
+
+ if (_currentNamespaceDecls [prefix] as string != nsUri) {
+ _currentNsPrefixes.Add (prefix);
+ _currentNamespaceDecls [prefix] = nsUri;
+ }
}
public override void WriteComment (string text)
_emitter.Done ();
_state = WriteState.Closed;
}
+
+ public override bool CanProcessAttributes {
+ get { return canProcessAttributes; }
+ }
#endregion
}
}
string version;\r
XmlQualifiedName [] extensionElementPrefixes;\r
XmlQualifiedName [] excludeResultPrefixes;\r
+ StringDictionary stylesheetNamespaces = new StringDictionary ();\r
\r
// below are newly introduced in XSLT 2.0\r
// elements::\r
string xpathDefaultNamespace = "";\r
XslDefaultValidation defaultValidation = XslDefaultValidation.Lax;\r
\r
+ public XmlQualifiedName [] ExtensionElementPrefixes {\r
+ get { return extensionElementPrefixes; }\r
+ }\r
+\r
+ public XmlQualifiedName [] ExcludeResultPrefixes {\r
+ get { return excludeResultPrefixes; }\r
+ }\r
+\r
+ public StringDictionary StylesheetNamespaces {\r
+ get { return stylesheetNamespaces; }\r
+ }\r
+\r
public ArrayList Imports {\r
get { return imports; }\r
}\r
version = c.Input.GetAttribute ("version", "");\r
extensionElementPrefixes = c.ParseQNameListAttribute ("extension-element-prefixes");\r
excludeResultPrefixes = c.ParseQNameListAttribute ("exclude-result-prefixes");\r
-
+ if (c.Input.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
+ do {
+ if (c.Input.Value == XsltNamespace)
+ continue;
+ this.stylesheetNamespaces.Add (c.Input.Name, c.Input.Value);
+ } while (c.Input.MoveToNextNamespace (XPathNamespaceScope.Local));
+ c.Input.MoveToParent ();
+ }
ProcessTopLevelElements ();\r
}