+2003-12-02 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+ * Compiler.cs : In FromListString(), it should use default ns,
+ not unqualified one.
+ * GenericOutputter.cs : CheckState() - attribute's Prefix should take
+ precedence. Doctype should be written even if SYSTEM id is absent.
+ Fixed possible multiple xmlns output.
+ * HtmlEmitter.cs :
+ - Encoding output using META element.
+ - Doctype name is fixed (html).
+ - Double quotation on PUBLIC and SYSTEM missing.
+ - Fixed incorrect tag name check for IMG.
+ - '>' should not be escaped.
+ * XmlWriterEmitter.cs :
+ Added newline before doctype. In WriteComment(), "--" and tail
+ '-' are not allowed (it escapes, while XmlWriter simply rejects).
+ * XslTransformProcessor.cs : cdata-section-elements should enclose
+ direct child tests only. Added PreserveWhitespace() (incomplete).
+ * XsltCompiledContext.cs : Implemented PreserveWhitespace() (incomplete).
+
+2003-11-28 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+ * IdPattern.cs : This should work against multiple ids.
+
2003-11-27 Ben Maurer <bmaurer@users.sourceforge.net>
* Compiler.cs
public class XslNameUtil
{
- static char [] wsChars = new char [] {' ', '\t', '\n', '\r'};
-
public static QName [] FromListString (string names, XPathNavigator current)
{
- string [] nameArray = names.Split (wsChars);
+ string [] nameArray = names.Split (XmlChar.WhitespaceChars);
int idx = 0;
for (int i = 0; i < nameArray.Length; i++)
if (nameArray [i] != String.Empty)
idx = 0;
for (int i = 0; i < nameArray.Length; i++)
if (nameArray [i] != String.Empty)
- qnames [idx++] = FromString (nameArray [i], current);
+ qnames [idx++] = FromString (nameArray [i], current, true);
return qnames;
}
public static QName FromString (string name, XPathNavigator current)
+ {
+ return FromString (name, current, false);
+ }
+
+ public static QName FromString (string name, XPathNavigator current, bool useDefaultXmlns)
{
if (current.NodeType == XPathNodeType.Attribute)
(current = current.Clone ()).MoveToParent ();
if (colon > 0)
return new QName (name.Substring (colon+ 1), current.GetNamespace (name.Substring (0, colon)));
else if (colon < 0)
- // Default namespace is not used for unprefixed names.
- return new QName (name, "");
+ return new QName (name, useDefaultXmlns ? current.GetNamespace (String.Empty) : "");
else
throw new ArgumentException ("Invalid name: " + name);
}
//Emit pending attributes
for (int i = 0; i < pendingAttributesPos; i++) {
Attribute attr = pendingAttributes [i];
- string prefix = _nsManager.LookupPrefix (attr.Namespace);
- if (prefix == null)
- prefix = attr.Prefix;
+ string prefix = attr.Prefix;
+ if (prefix == String.Empty)
+ prefix = _nsManager.LookupPrefix (attr.Namespace);
_emitter.WriteAttributeString (prefix, attr.LocalName, attr.Namespace, attr.Value);
}
foreach (string prefix in _currentNsPrefixes) {
if (_state == WriteState.Prolog) {
//Seems to be the first element - take care of Doctype
- if (_currentOutput.DoctypeSystem != null)
+ // 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);
}
_nsManager.AddNamespace (prefix, nsUri);
if (_currentNamespaceDecls [prefix] as string != nsUri) {
- _currentNsPrefixes.Add (prefix);
+ if (!_currentNsPrefixes.Contains (prefix))
+ _currentNsPrefixes.Add (prefix);
_currentNamespaceDecls [prefix] = nsUri;
}
}
bool openAttribute;
int xmlDepth;
bool indent;
+ Encoding outputEncoding;
public HtmlEmitter (TextWriter writer, XslOutput output)
{
indent = !(output.Indent == "no");
elementNameStack = new Stack ();
xmlDepth = -1;
+ outputEncoding = output.Encoding;
}
public override void WriteStartDocument (StandaloneType standalone)
{
- // do nothing
}
public override void WriteEndDocument ()
public override void WriteDocType (string name, string publicId, string systemId)
{
- writer.Write ("<!DOCTYPE ");
- writer.Write (name);
- writer.Write (' ');
+ writer.Write ("<!DOCTYPE html ");
if (publicId != null && publicId != String.Empty) {
- writer.Write ("PUBLIC ");
+ writer.Write ("PUBLIC \"");
writer.Write (publicId);
- writer.Write (' ');
+ writer.Write ("\" ");
writer.Write (systemId);
} else if (systemId != null && systemId != String.Empty) {
- writer.Write ("SYSTEM ");
+ writer.Write ("SYSTEM \"");
writer.Write (systemId);
+ writer.Write ('\"');
}
- writer.Write ('>');
+ writer.Write (">\r\n");
}
private void CloseAttribute ()
CloseAttribute ();
writer.Write ('>');
openElement = false;
+
+ if (outputEncoding != null && elementNameStack.Count > 0) {
+ string name = elementNameStack.Peek () as string;
+ if (name.ToUpper () == "HEAD") {
+ WriteStartElement (String.Empty, "META", String.Empty);
+ WriteAttributeString (String.Empty, "http-equiv", String.Empty, "Content-Type");
+ WriteAttributeString (String.Empty, "content", String.Empty, "text/html; charset=" + outputEncoding.WebName);
+ WriteEndElement ();
+ }
+ }
}
// FIXME: check all HTML elements' indentation.
case "COL":
case "FRAME":
case "HR":
- case "IMAGE":
+ case "IMG":
case "INPUT":
case "ISINDEX":
case "LINK":
writer.Write ("<");
start = i;
break;
- case '>':
- writer.Write (text.ToCharArray (), start, i - start);
- writer.Write (">");
- start = i;
- break;
case '\'':
writer.Write (text.ToCharArray (), start, i - start);
writer.Write ("'");
public override void WriteDocType (string type, string publicId, string systemId)
{
+ writer.WriteWhitespace (Environment.NewLine);
writer.WriteDocType (type, publicId, systemId, null);
}
}
public override void WriteComment (string text) {
- writer.WriteComment (text);
+ if (text.IndexOf ("--") >= 0)
+ text = text.Replace ("--", "- -");
+
+ if (text.EndsWith ("-"))
+ writer.WriteComment (text + ' ');
+ else
+ writer.WriteComment (text);
}
public override void WriteProcessingInstruction (string name, string text)
namespace Mono.Xml.Xsl {
public class XslTransformProcessor {
- static char [] wsChars = new char [] {' ', '\t', '\n', '\r'};
-
CompiledStylesheet compiledStyle;
XslStylesheet style;
public bool PushCDataState (string name, string ns)
{
- if (insideCDataSectionElements)
- return false;
+// if (insideCDataSectionElements)
+// return false;
for (int i = 0; i < Output.CDataSectionElements.Length; i++) {
XmlQualifiedName qname = Output.CDataSectionElements [i];
if (qname.Name == name && qname.Namespace == ns) {
return true;
}
}
+ this.insideCDataSectionElements = false;
+ Out.InsideCDataSection = false; //
return false;
}
- public void PopCDataState ()
+ public void PopCDataState (bool isCData)
{
- Out.InsideCDataSection = false;
- this.insideCDataSectionElements = false;
+ Out.InsideCDataSection = this.insideCDataSectionElements = isCData;
+ }
+
+ public bool PreserveWhitespace ()
+ {
+ return XPathContext.PreserveWhitespace (CurrentNode);
}
}
}
}
public override int CompareDocument (string baseUri, string nextBaseUri) { throw new NotImplementedException (); }
- public override bool PreserveWhitespace (XPathNavigator nav) { throw new NotImplementedException (); }
+
+ public override bool PreserveWhitespace (XPathNavigator nav)
+ {
+ XPathNavigator tmp = nav.Clone ();
+ switch (tmp.NodeType) {
+ case XPathNodeType.Root:
+ return false;
+ case XPathNodeType.Element:
+ break;
+ default:
+ tmp.MoveToParent ();
+ break;
+ }
+
+ for (; tmp.NodeType == XPathNodeType.Element; tmp.MoveToParent ()) {
+ object o = p.CompiledStyle.Style.SpaceControls [new XmlQualifiedName (tmp.LocalName, tmp.NamespaceURI)];
+ if (o == null)
+ continue;
+ XmlSpace space = (XmlSpace) o;
+ switch ((XmlSpace) o) {
+ case XmlSpace.Preserve:
+ return true;
+ case XmlSpace.Default:
+ return false;
+ // None: continue.
+ }
+ }
+ return true;
+ }
+
public override bool Whitespace { get { throw new NotImplementedException (); }}
}