(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / Mono.Xml.Xsl / Compiler.cs
bloba18be78557346722024445abdd29edc90aee14fe
1 //
2 // Compiler.cs
3 //
4 // Authors:
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System;
34 using System.CodeDom;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Security.Policy;
38 using System.Xml;
39 using System.Xml.Schema;
40 using System.Xml.XPath;
41 using System.Xml.Xsl;
42 using System.IO;
44 using Mono.Xml.Xsl.Operations;
45 using Mono.Xml.XPath;
47 using QName = System.Xml.XmlQualifiedName;
49 namespace Mono.Xml.Xsl
51 internal class CompiledStylesheet {
52 XslStylesheet style;
53 Hashtable globalVariables;
54 Hashtable attrSets;
55 ExpressionStore exprStore;
56 XmlNamespaceManager nsMgr;
57 Hashtable keys;
58 Hashtable outputs;
59 Hashtable decimalFormats;
60 MSXslScriptManager msScripts;
62 public CompiledStylesheet (XslStylesheet style, Hashtable globalVariables, Hashtable attrSets, ExpressionStore exprStore, XmlNamespaceManager nsMgr, Hashtable keys, Hashtable outputs, Hashtable decimalFormats,
63 MSXslScriptManager msScripts)
65 this.style = style;
66 this.globalVariables = globalVariables;
67 this.attrSets = attrSets;
68 this.exprStore = exprStore;
69 this.nsMgr = nsMgr;
70 this.keys = keys;
71 this.outputs = outputs;
72 this.decimalFormats = decimalFormats;
73 this.msScripts = msScripts;
75 public Hashtable Variables {get{return globalVariables;}}
76 public XslStylesheet Style { get { return style; }}
77 public ExpressionStore ExpressionStore {get{return exprStore;}}
78 public XmlNamespaceManager NamespaceManager {get{return nsMgr;}}
79 public Hashtable Keys {get { return keys;}}
80 public Hashtable Outputs { get { return outputs; }}
82 public MSXslScriptManager ScriptManager {
83 get { return msScripts; }
87 public XslDecimalFormat LookupDecimalFormat (QName name)
89 XslDecimalFormat ret = decimalFormats [name] as XslDecimalFormat;
90 if (ret == null && name == QName.Empty)
91 return XslDecimalFormat.Default;
92 return ret;
95 public XslGeneralVariable ResolveVariable (QName name)
97 return (XslGeneralVariable)globalVariables [name];
100 public XslAttributeSet ResolveAttributeSet (QName name)
102 return (XslAttributeSet)attrSets [name];
106 internal class Compiler : IStaticXsltContext {
107 public const string XsltNamespace = "http://www.w3.org/1999/XSL/Transform";
109 ArrayList inputStack = new ArrayList ();
110 XPathNavigator currentInput;
112 Stack styleStack = new Stack ();
113 XslStylesheet currentStyle;
115 Hashtable globalVariables = new Hashtable ();
116 Hashtable attrSets = new Hashtable ();
118 ExpressionStore exprStore = new ExpressionStore ();
119 XmlNamespaceManager nsMgr = new XmlNamespaceManager (new NameTable ());
121 XmlResolver res;
122 Evidence evidence;
124 XslStylesheet rootStyle;
125 Hashtable outputs = new Hashtable ();
126 bool keyCompilationMode;
128 public CompiledStylesheet Compile (XPathNavigator nav, XmlResolver res, Evidence evidence)
130 this.parser = new XPathParser (this);
131 this.res = res;
132 if (res == null)
133 this.res = new XmlUrlResolver ();
134 this.evidence = evidence;
136 if (!nav.MoveToFirstChild ())
137 throw new XsltCompileException ("Stylesheet root element must be either \"stylesheet\" or \"transform\" or any literal element.", null, nav);
139 outputs [""] = new XslOutput ("");
141 while (nav.NodeType != XPathNodeType.Element) nav.MoveToNext();
143 PushInputDocument (nav);
144 if (nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml))
146 do {
147 nsMgr.AddNamespace (nav.LocalName, nav.Value);
148 } while (nav.MoveToNextNamespace (XPathNamespaceScope.ExcludeXml));
149 nav.MoveToParent ();
151 this.rootStyle = new XslStylesheet (this);
153 return new CompiledStylesheet (rootStyle, globalVariables, attrSets, exprStore, nsMgr, rootStyle.Keys, outputs, decimalFormats, msScripts);
156 MSXslScriptManager msScripts = new MSXslScriptManager ();
157 public MSXslScriptManager ScriptManager {
158 get { return msScripts; }
161 public bool KeyCompilationMode {
162 get { return keyCompilationMode; }
163 set { keyCompilationMode = value; }
166 internal Evidence Evidence {
167 get { return evidence; }
170 #region Input
171 public XPathNavigator Input {
172 get { return currentInput; }
175 public XslStylesheet CurrentStylesheet {
176 get { return currentStyle; }
179 public void PushStylesheet (XslStylesheet style)
181 if (currentStyle != null) styleStack.Push (currentStyle);
182 currentStyle = style;
185 public void PopStylesheet ()
187 if (styleStack.Count == 0)
188 currentStyle = null;
189 else
190 currentStyle = (XslStylesheet)styleStack.Pop ();
193 public void PushInputDocument (string url)
195 // todo: detect recursion
196 Uri baseUriObj = (Input.BaseURI == String.Empty) ? null : new Uri (Input.BaseURI);
197 Uri absUri = res.ResolveUri (baseUriObj, url);
198 using (Stream s = (Stream)res.GetEntity (absUri, null, typeof(Stream)))
201 XmlValidatingReader vr = new XmlValidatingReader (new XmlTextReader (absUri.ToString (), s, nsMgr.NameTable));
202 vr.ValidationType = ValidationType.None;
203 XPathNavigator n = new XPathDocument (vr, XmlSpace.Preserve).CreateNavigator ();
204 vr.Close ();
205 n.MoveToFirstChild ();
206 do {
207 if (n.NodeType == XPathNodeType.Element)
208 break;
209 } while (n.MoveToNext ());
210 PushInputDocument (n);
214 private void PushInputDocument (XPathNavigator nav)
216 for (int i = 0; i < inputStack.Count; i++) {
217 XPathNavigator cur = (XPathNavigator) inputStack [i];
218 if (cur.BaseURI == nav.BaseURI) {
219 IXmlLineInfo li = currentInput as IXmlLineInfo;
220 throw new XsltCompileException (null,
221 currentInput.BaseURI,
222 li != null ? li.LineNumber : 0,
223 li != null ? li.LinePosition : 0);
226 if (currentInput != null)
227 inputStack.Add (currentInput);
228 currentInput = nav;
231 public void PopInputDocument ()
233 int last = inputStack.Count - 1;
234 currentInput = (XPathNavigator) inputStack [last];
235 inputStack.RemoveAt (last);
238 public QName ParseQNameAttribute (string localName)
240 return ParseQNameAttribute (localName, String.Empty);
242 public QName ParseQNameAttribute (string localName, string ns)
244 return XslNameUtil.FromString (Input.GetAttribute (localName, ns), Input);
247 public QName [] ParseQNameListAttribute (string localName)
249 return ParseQNameListAttribute (localName, String.Empty);
252 public QName [] ParseQNameListAttribute (string localName, string ns)
254 string s = GetAttribute (localName, ns);
255 if (s == null) return null;
257 string [] names = s.Split (new char [] {' ', '\r', '\n', '\t'});
258 QName [] ret = new QName [names.Length];
260 for (int i = 0; i < names.Length; i++)
261 ret [i] = XslNameUtil.FromString (names [i], Input);
263 return ret;
266 public bool ParseYesNoAttribute (string localName, bool defaultVal)
268 return ParseYesNoAttribute (localName, String.Empty, defaultVal);
271 public bool ParseYesNoAttribute (string localName, string ns, bool defaultVal)
273 string s = GetAttribute (localName, ns);
275 switch (s) {
276 case null: return defaultVal;
277 case "yes": return true;
278 case "no": return false;
279 default:
280 throw new XsltCompileException ("invalid value for " + localName, null, Input);
284 public string GetAttribute (string localName)
286 return GetAttribute (localName, String.Empty);
289 public string GetAttribute (string localName, string ns)
291 if (!Input.MoveToAttribute (localName, ns))
292 return null;
294 string ret = Input.Value;
295 Input.MoveToParent ();
296 return ret;
298 public XslAvt ParseAvtAttribute (string localName)
300 return ParseAvtAttribute (localName, String.Empty);
302 public XslAvt ParseAvtAttribute (string localName, string ns)
304 return ParseAvt (GetAttribute (localName, ns));
307 public void AssertAttribute (string localName)
309 AssertAttribute (localName, "");
311 public void AssertAttribute (string localName, string ns)
313 if (Input.GetAttribute (localName, ns) == null)
314 throw new XsltCompileException ("Was expecting the " + localName + " attribute.", null, Input);
317 public XslAvt ParseAvt (string s)
319 if (s == null) return null;
320 return new XslAvt (s, this);
324 #endregion
325 #region Compile
326 public Pattern CompilePattern (string pattern, XPathNavigator loc)
328 if (pattern == null || pattern == "") return null;
329 Pattern p = Pattern.Compile (pattern, this);
330 if (p == null)
331 throw new XsltCompileException (String.Format ("Invalid pattern '{0}'.", pattern), null, loc);
332 exprStore.AddPattern (p, this);
334 return p;
337 internal XPathParser parser;
338 internal CompiledExpression CompileExpression (string expression)
340 return CompileExpression (expression, false);
343 internal CompiledExpression CompileExpression (string expression, bool isKey)
345 if (expression == null || expression == "") return null;
347 Expression expr = parser.Compile (expression);
348 if (isKey)
349 expr = new ExprKeyContainer (expr);
350 CompiledExpression e = new CompiledExpression (expression, expr);
352 exprStore.AddExpression (e, this);
354 return e;
357 public XslOperation CompileTemplateContent ()
359 return CompileTemplateContent (XPathNodeType.All);
362 public XslOperation CompileTemplateContent (XPathNodeType parentType)
364 return new XslTemplateContent (this, parentType);
366 #endregion
367 #region Variables
368 public void AddGlobalVariable (XslGlobalVariable var)
370 globalVariables [var.Name] = var;
373 public void AddAttributeSet (XslAttributeSet set)
375 XslAttributeSet existing = attrSets [set.Name] as XslAttributeSet;
376 // The latter set will have higher priority
377 if (existing != null) {
378 existing.Merge (set);
379 attrSets [set.Name] = existing;
381 else
382 attrSets [set.Name] = set;
385 VariableScope curVarScope;
387 public void PushScope ()
389 curVarScope = new VariableScope (curVarScope);
392 public VariableScope PopScope ()
394 curVarScope.giveHighTideToParent ();
395 VariableScope cur = curVarScope;
396 curVarScope = curVarScope.Parent;
397 return cur;
400 public int AddVariable (XslLocalVariable v)
402 if (curVarScope == null)
403 throw new XsltCompileException ("Not initialized variable", null, Input);
405 return curVarScope.AddVariable (v);
408 public void AddSort (XPathExpression e, Sort s)
410 exprStore.AddSort (e, s);
412 public VariableScope CurrentVariableScope { get { return curVarScope; }}
413 #endregion
415 #region Scope (version, {excluded, extension} namespaces)
416 [MonoTODO ("This will work, but is *very* slow")]
417 public bool IsExtensionNamespace (string nsUri)
419 if (nsUri == XsltNamespace) return true;
421 XPathNavigator nav = Input.Clone ();
422 XPathNavigator nsScope = nav.Clone ();
423 do {
424 bool isXslt = nav.NamespaceURI == XsltNamespace;
425 nsScope.MoveTo (nav);
426 if (nav.MoveToFirstAttribute ()) {
427 do {
428 if (nav.LocalName == "extension-element-prefixes" &&
429 nav.NamespaceURI == (isXslt ? String.Empty : XsltNamespace))
432 foreach (string ns in nav.Value.Split (' '))
433 if (nsScope.GetNamespace (ns == "#default" ? "" : ns) == nsUri)
434 return true;
436 } while (nav.MoveToNextAttribute ());
437 nav.MoveToParent ();
439 } while (nav.MoveToParent ());
441 return false;
444 public Hashtable GetNamespacesToCopy ()
446 Hashtable ret = new Hashtable ();
448 XPathNavigator nav = Input.Clone ();
449 XPathNavigator nsScope = nav.Clone ();
451 if (nav.MoveToFirstNamespace (XPathNamespaceScope.Local)) {
452 do {
453 if (nav.Value != XsltNamespace && !ret.Contains (nav.Name))
454 ret.Add (nav.Name, nav.Value);
455 } while (nav.MoveToNextNamespace (XPathNamespaceScope.Local));
456 nav.MoveToParent ();
459 do {
460 bool isXslt = nav.NamespaceURI == XsltNamespace;
461 nsScope.MoveTo (nav);
463 if (nav.MoveToFirstAttribute()) {
464 do {
465 if ((nav.LocalName == "extension-element-prefixes" || nav.LocalName == "exclude-result-prefixes") &&
466 nav.NamespaceURI == (isXslt ? String.Empty : XsltNamespace))
468 foreach (string ns in nav.Value.Split (' ')) {
469 string realNs = ns == "#default" ? "" : ns;
471 if ((string)ret [realNs] == nsScope.GetNamespace (realNs))
472 ret.Remove (realNs);
475 } while (nav.MoveToNextAttribute ());
476 nav.MoveToParent();
478 } while (nav.MoveToParent ());
480 return ret;
482 #endregion
484 #region Decimal Format
485 Hashtable decimalFormats = new Hashtable ();
487 public void CompileDecimalFormat ()
489 QName nm = ParseQNameAttribute ("name");
490 try {
491 if (nm.Name != String.Empty)
492 XmlConvert.VerifyNCName (nm.Name);
493 } catch (XmlException ex) {
494 throw new XsltCompileException ("Invalid qualified name.", ex, Input);
496 XslDecimalFormat df = new XslDecimalFormat (this);
498 if (decimalFormats.Contains (nm))
499 ((XslDecimalFormat)decimalFormats [nm]).CheckSameAs (df);
500 else
501 decimalFormats [nm] = df;
503 #endregion
504 #region Static XSLT context
505 Expression IStaticXsltContext.TryGetVariable (string nm)
507 if (curVarScope == null)
508 return null;
510 XslLocalVariable var = curVarScope.ResolveStatic (XslNameUtil.FromString (nm, Input));
512 if (var == null)
513 return null;
515 return new XPathVariableBinding (var);
518 Expression IStaticXsltContext.TryGetFunction (QName name, FunctionArguments args)
520 string ns = GetNsm ().LookupNamespace (name.Namespace, false);
521 if (ns == XslStylesheet.MSXsltNamespace && name.Name == "node-set")
522 return new MSXslNodeSet (args);
524 if (ns != "")
525 return null;
527 switch (name.Name) {
528 case "current": return new XsltCurrent (args);
529 case "unparsed-entity-uri": return new XsltUnparsedEntityUri (args);
530 case "element-available": return new XsltElementAvailable (args, this);
531 case "system-property": return new XsltSystemProperty (args, this);
532 case "function-available": return new XsltFunctionAvailable (args, this);
533 case "generate-id": return new XsltGenerateId (args);
534 case "format-number": return new XsltFormatNumber (args, this);
535 case "key":
536 if (KeyCompilationMode)
537 throw new XsltCompileException ("Cannot use key() function inside key definition.", null, this.Input);
538 return new XsltKey (args, this);
539 case "document": return new XsltDocument (args, this);
542 return null;
545 QName IStaticXsltContext.LookupQName (string s)
547 return XslNameUtil.FromString (s, Input);
550 XmlNamespaceManager IStaticXsltContext.GetNsm ()
552 return new XPathNavigatorNsm (Input);
555 public XmlNamespaceManager GetNsm ()
557 return new XPathNavigatorNsm (Input);
559 #endregion
560 public void CompileOutput ()
562 XPathNavigator n = Input;
563 string uri = n.GetAttribute ("href", "");
564 XslOutput output = outputs [uri] as XslOutput;
565 if (output == null) {
566 output = new XslOutput (uri);
567 outputs.Add (uri, output);
569 output.Fill (n);
573 internal class VariableScope {
574 Hashtable variables;
575 VariableScope parent;
576 int nextSlot = 0;
577 int highTide = 0; // this will be the size of the stack frame
579 internal void giveHighTideToParent ()
581 if (parent != null)
582 parent.highTide = System.Math.Max (VariableHighTide, parent.VariableHighTide);
585 public int VariableHighTide { get { return System.Math.Max (highTide, nextSlot); }}
587 public VariableScope (VariableScope parent)
589 this.parent = parent;
590 if (parent != null)
591 this.nextSlot = parent.nextSlot;
594 public VariableScope Parent { get { return parent; }}
596 public int AddVariable (XslLocalVariable v)
598 if (variables == null)
599 variables = new Hashtable ();
601 variables [v.Name] = v;
602 return nextSlot++;
605 public XslLocalVariable ResolveStatic (QName name)
607 for (VariableScope s = this; s != null; s = s.Parent) {
608 if (s.variables == null) continue;
609 XslLocalVariable v = s.variables [name] as XslLocalVariable;
610 if (v != null) return v;
612 return null;
615 public XslLocalVariable Resolve (XslTransformProcessor p, QName name)
617 for (VariableScope s = this; s != null; s = s.Parent) {
618 if (s.variables == null) continue;
619 XslLocalVariable v = s.variables [name] as XslLocalVariable;
620 if (v != null && v.IsEvaluated (p))
621 return v;
624 return null;
628 internal class Sort {
629 string lang;
630 XmlDataType dataType;
631 XmlSortOrder order;
632 XmlCaseOrder caseOrder;
634 XslAvt langAvt, dataTypeAvt, orderAvt, caseOrderAvt;
635 XPathExpression expr;
637 public Sort (Compiler c)
639 expr = c.CompileExpression (c.GetAttribute ("select"));
640 if (expr == null)
641 expr = c.CompileExpression ("string(.)");
643 langAvt = c.ParseAvtAttribute ("lang");
644 dataTypeAvt = c.ParseAvtAttribute ("data-type");
645 orderAvt = c.ParseAvtAttribute ("order");
646 caseOrderAvt = c.ParseAvtAttribute ("case-order");
648 // Precalc whatever we can
649 lang = ParseLang (XslAvt.AttemptPreCalc (ref langAvt));
650 dataType = ParseDataType (XslAvt.AttemptPreCalc (ref dataTypeAvt));
651 order = ParseOrder (XslAvt.AttemptPreCalc (ref orderAvt));
652 caseOrder = ParseCaseOrder (XslAvt.AttemptPreCalc (ref caseOrderAvt));
656 string ParseLang (string value)
658 return value;
661 XmlDataType ParseDataType (string value)
663 switch (value)
665 case "number":
666 return XmlDataType.Number;
667 case "text":
668 case null:
669 default:
670 return XmlDataType.Text;
674 XmlSortOrder ParseOrder (string value)
676 switch (value)
678 case "descending":
679 return XmlSortOrder.Descending;
680 case "ascending":
681 case null:
682 default:
683 return XmlSortOrder.Ascending;
687 XmlCaseOrder ParseCaseOrder (string value)
689 switch (value)
691 case "upper-first":
692 return XmlCaseOrder.UpperFirst;
693 case "lower-first":
694 return XmlCaseOrder.LowerFirst;
695 case null:
696 default:
697 return XmlCaseOrder.None;
702 public void AddToExpr (XPathExpression e, XslTransformProcessor p)
704 e.AddSort (
705 expr,
706 orderAvt == null ? order : ParseOrder (orderAvt.Evaluate (p)),
707 caseOrderAvt == null ? caseOrder: ParseCaseOrder (caseOrderAvt.Evaluate (p)),
708 langAvt == null ? lang : ParseLang (langAvt.Evaluate (p)),
709 dataTypeAvt == null ? dataType : ParseDataType (dataTypeAvt.Evaluate (p))
714 internal class ExpressionStore {
715 Hashtable exprToSorts;
717 public void AddExpression (XPathExpression e, Compiler c)
721 public void AddPattern (Pattern p, Compiler c)
725 public void AddSort (XPathExpression e, Sort s)
727 if (exprToSorts == null)
728 exprToSorts = new Hashtable ();
730 if (exprToSorts.Contains (e))
731 ((ArrayList)exprToSorts [e]).Add (s);
732 else {
733 ArrayList a = new ArrayList ();
734 a.Add (s);
735 exprToSorts [e] = a;
739 public XPathExpression PrepForExecution (XPathExpression e, XslTransformProcessor p)
741 if (exprToSorts != null && exprToSorts.Contains (e))
743 XPathExpression expr = e.Clone ();
744 foreach (Sort s in (ArrayList)exprToSorts [e])
745 s.AddToExpr (expr,p);
746 return expr;
748 return e;
751 public bool PatternMatches (Pattern p, XslTransformProcessor proc, XPathNavigator n)
753 return p.Matches (n, proc.XPathContext);
757 internal class XslNameUtil
759 public static QName [] FromListString (string names, XPathNavigator current)
761 string [] nameArray = names.Split (XmlChar.WhitespaceChars);
762 int idx = 0;
763 for (int i = 0; i < nameArray.Length; i++)
764 if (nameArray [i] != String.Empty)
765 idx++;
767 XmlQualifiedName [] qnames = new XmlQualifiedName [idx];
769 idx = 0;
770 for (int i = 0; i < nameArray.Length; i++)
771 if (nameArray [i] != String.Empty)
772 qnames [idx++] = FromString (nameArray [i], current, true);
774 return qnames;
777 public static QName FromString (string name, XPathNavigator current)
779 return FromString (name, current, false);
782 public static QName FromString (string name, XPathNavigator current, bool useDefaultXmlns)
784 if (current.NodeType == XPathNodeType.Attribute)
785 (current = current.Clone ()).MoveToParent ();
787 int colon = name.IndexOf (':');
788 if (colon > 0)
789 return new QName (name.Substring (colon+ 1), current.GetNamespace (name.Substring (0, colon)));
790 else if (colon < 0)
791 return new QName (name, useDefaultXmlns ? current.GetNamespace (String.Empty) : "");
792 else
793 throw new ArgumentException ("Invalid name: " + name);
796 public static QName FromString (string name, XmlNamespaceManager ctx)
798 int colon = name.IndexOf (':');
799 if (colon > 0)
800 return new QName (name.Substring (colon + 1), ctx.LookupNamespace (name.Substring (0, colon), false));
801 else if (colon < 0)
802 // Default namespace is not used for unprefixed names.
803 return new QName (name, "");
804 else
805 throw new ArgumentException ("Invalid name: " + name);
808 public static string LocalNameOf (string name)
810 int colon = name.IndexOf (':');
811 if (colon > 0)
812 return name.Substring (colon + 1);
813 else if (colon < 0)
814 return name;
815 else
816 throw new ArgumentException ("Invalid name: " + name);
820 internal class XPathNavigatorNsm : XmlNamespaceManager {
821 XPathNavigator nsScope;
823 public XPathNavigatorNsm (XPathNavigator n) : base (n.NameTable) {
824 nsScope = n.Clone ();
825 if (nsScope.NodeType == XPathNodeType.Attribute)
826 nsScope.MoveToParent ();
829 public override string DefaultNamespace { get { return String.Empty; }}
831 #if NET_2_0
832 public override string LookupNamespace (string prefix, bool atomizedNames)
833 #else
834 internal override string LookupNamespace (string prefix, bool atomizedNames)
835 #endif
837 if (prefix == "" || prefix == null)
838 return "";
840 return nsScope.GetNamespace (prefix);