* Form.cs: Provide meaningful message when MdiParent is assigned a
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl.Operations / XslElement.cs
index ec9d0d57510998804d30a782443594ba4e0383a4..19f2d7d9d45f7cedad236738ef62ca6c9be26400 100644 (file)
@@ -9,6 +9,27 @@
 // (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.Xml;
@@ -18,45 +39,53 @@ using System.Xml.Xsl;
 using QName = System.Xml.XmlQualifiedName;
 
 namespace Mono.Xml.Xsl.Operations {    
-       public class XslElement : XslCompiledElement {
+       internal class XslElement : XslCompiledElement {
                XslAvt name, ns;
                string calcName, calcNs, calcPrefix;
-               XmlNamespaceManager nsm;
+               Hashtable nsDecls;
                bool isEmptyElement;
 
                XslOperation value;
                XmlQualifiedName [] useAttributeSets;
 
-               XPathNavigator nav;
-               
                public XslElement (Compiler c) : base (c) {}
                protected override void Compile (Compiler c)
                {
-                       nav = c.Input.Clone ();
-
                        name = c.ParseAvtAttribute ("name");
                        ns = c.ParseAvtAttribute ("namespace");
-                       
+                       nsDecls = c.GetNamespacesToCopy ();
                        calcName = XslAvt.AttemptPreCalc (ref name);
                        
                        if (calcName != null) {
                                int colonAt = calcName.IndexOf (':');
+                               if (colonAt == 0)
+                                       throw new XsltCompileException ("Invalid name attribute", null, c.Input);
                                calcPrefix = colonAt < 0 ? String.Empty : calcName.Substring (0, colonAt);
-                               calcName = colonAt < 0 ? calcName : calcName.Substring (colonAt + 1, calcName.Length - colonAt - 1);
-                               if (ns == null)
+                               if (colonAt > 0)
+                                       calcName = calcName.Substring (colonAt + 1);
+
+                               try {
+                                       XmlConvert.VerifyNCName (calcName);
+                                       if (calcPrefix != String.Empty)
+                                               XmlConvert.VerifyNCName (calcPrefix);
+                               } catch (XmlException ex) {
+                                       throw new XsltCompileException ("Invalid name attribute", ex, c.Input);
+                               }
+
+                               if (ns == null) {
                                        calcNs = c.Input.GetNamespace (calcPrefix);
+                                       if (calcPrefix != String.Empty && calcNs == String.Empty)
+                                               throw new XsltCompileException ("Invalid name attribute", null, c.Input);
+                               }
                        } else if (ns != null)
                                calcNs = XslAvt.AttemptPreCalc (ref ns);
                        
-                       if (ns == null && calcNs == null)
-                               nsm = c.GetNsm ();
-                       
                        useAttributeSets = c.ParseQNameListAttribute ("use-attribute-sets");
                        
                        isEmptyElement = c.Input.IsEmptyElement;
 
                        if (c.Input.MoveToFirstChild ()) {
-                               value = c.CompileTemplateContent ();
+                               value = c.CompileTemplateContent (XPathNodeType.Element);
                                c.Input.MoveToParent ();
                        }
                }
@@ -68,36 +97,26 @@ namespace Mono.Xml.Xsl.Operations {
                        localName = nm = calcName != null ? calcName : name.Evaluate (p);
                        nmsp = calcNs != null ? calcNs : ns != null ? ns.Evaluate (p) : null;
 
-                       if (nmsp == null) {
-                               QName q = XslNameUtil.FromString (nm, nsm);
-                               localName = q.Name;
+                       QName q = XslNameUtil.FromString (nm, nsDecls);
+                       localName = q.Name;
+                       if (nmsp == null)
                                nmsp = q.Namespace;
-                               int colonAt = nm.IndexOf (':');
-                               if (colonAt > 0)
-                                       calcPrefix = nm.Substring (0, colonAt);
-                       }
-                       prefix = calcPrefix != null ? calcPrefix : String.Empty;
+                       int colonAt = nm.IndexOf (':');
+                       if (colonAt > 0)
+                               calcPrefix = nm.Substring (0, colonAt);
+                       else if (colonAt == 0)
+                               // raises an error
+                               XmlConvert.VerifyNCName (String.Empty);
 
-#if false
-                       if (calcPrefix == String.Empty) {
-                               if (nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml)) {
-                                       do {
-                                               if (nav.Value == nmsp) {
-//                                                     prefix = nav.Name;
-                                                       break;
-                                               }
-                                       } while (nav.MoveToNextNamespace (XPathNamespaceScope.ExcludeXml));
-                                       nav.MoveToParent ();
-                               }
-                       }
-#endif
+                       prefix = calcPrefix != null ? calcPrefix : String.Empty;
 
-                       XmlConvert.VerifyName (nm);
+                       if (prefix != String.Empty)
+                               XmlConvert.VerifyNCName (prefix);
+                       XmlConvert.VerifyNCName (localName);
 
                        bool isCData = p.InsideCDataElement;
-                       p.PushCDataState (localName, nmsp);
+                       p.PushElementState (prefix, localName, nmsp, false);
                        p.Out.WriteStartElement (prefix, localName, nmsp);
-                       p.TryStylesheetNamespaceOutput (null);
 
                        if (useAttributeSets != null)
                                foreach (XmlQualifiedName s in useAttributeSets)