The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.XsltOld \ ElementAction

  1. //------------------------------------------------------------------------------
  2. // <copyright file="ElementAction.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml.Xsl.XsltOld
  16. {
  17.     using Res = System.Xml.Utils.Res;
  18.     using System;
  19.     using System.Diagnostics;
  20.     using System.Xml;
  21.     using System.Xml.XPath;
  22.    
  23.     internal class ElementAction : ContainerAction
  24.     {
  25.         private const int NameDone = 2;
  26.        
  27.         private Avt nameAvt;
  28.         private Avt nsAvt;
  29.         private bool empty;
  30.         private InputScopeManager manager;
  31.         // Compile time precalculated AVTs
  32.         private string name;
  33.         private string nsUri;
  34.         private PrefixQName qname;
  35.         // When we not have AVTs at all we can do this. null otherwise.
  36.         internal ElementAction()
  37.         {
  38.         }
  39.        
  40.         private static PrefixQName CreateElementQName(string name, string nsUri, InputScopeManager manager)
  41.         {
  42.             if (nsUri == Keywords.s_XmlnsNamespace) {
  43.                 throw XsltException.Create(Res.Xslt_ReservedNS, nsUri);
  44.             }
  45.            
  46.             PrefixQName qname = new PrefixQName();
  47.             qname.SetQName(name);
  48.            
  49.             if (nsUri == null) {
  50.                 qname.Namespace = manager.ResolveXmlNamespace(qname.Prefix);
  51.             }
  52.             else {
  53.                 qname.Namespace = nsUri;
  54.             }
  55.             return qname;
  56.         }
  57.        
  58.         internal override void Compile(Compiler compiler)
  59.         {
  60.             CompileAttributes(compiler);
  61.             CheckRequiredAttribute(compiler, this.nameAvt, Keywords.s_Name);
  62.            
  63.             this.name = PrecalculateAvt(ref this.nameAvt);
  64.             this.nsUri = PrecalculateAvt(ref this.nsAvt);
  65.            
  66.             // if both name and ns are not AVT we can calculate qname at compile time and will not need namespace manager anymore
  67.             if (this.nameAvt == null && this.nsAvt == null) {
  68.                 if (this.name != Keywords.s_Xmlns) {
  69.                     this.qname = CreateElementQName(this.name, this.nsUri, compiler.CloneScopeManager());
  70.                 }
  71.             }
  72.             else {
  73.                 this.manager = compiler.CloneScopeManager();
  74.             }
  75.            
  76.             if (compiler.Recurse()) {
  77.                 Debug.Assert(this.empty == false);
  78.                 CompileTemplate(compiler);
  79.                 compiler.ToParent();
  80.             }
  81.             this.empty = (this.containedActions == null);
  82.         }
  83.        
  84.         internal override bool CompileAttribute(Compiler compiler)
  85.         {
  86.             string name = compiler.Input.LocalName;
  87.             string value = compiler.Input.Value;
  88.             if (Keywords.Equals(name, compiler.Atoms.Name)) {
  89.                 this.nameAvt = Avt.CompileAvt(compiler, value);
  90.             }
  91.             else if (Keywords.Equals(name, compiler.Atoms.Namespace)) {
  92.                 this.nsAvt = Avt.CompileAvt(compiler, value);
  93.             }
  94.             else if (Keywords.Equals(name, compiler.Atoms.UseAttributeSets)) {
  95.                 AddAction(compiler.CreateUseAttributeSetsAction());
  96.             }
  97.             else {
  98.                 return false;
  99.             }
  100.            
  101.             return true;
  102.         }
  103.        
  104.         internal override void Execute(Processor processor, ActionFrame frame)
  105.         {
  106.             Debug.Assert(processor != null && frame != null);
  107.            
  108.             switch (frame.State) {
  109.                 case Initialized:
  110.                     if (this.qname != null) {
  111.                         frame.CalulatedName = this.qname;
  112.                     }
  113.                     else {
  114.                         frame.CalulatedName = CreateElementQName(this.nameAvt == null ? this.name : this.nameAvt.Evaluate(processor, frame), this.nsAvt == null ? this.nsUri : this.nsAvt.Evaluate(processor, frame), this.manager);
  115.                     }
  116.                     goto case NameDone;
  117.                     break;
  118.                 case NameDone:
  119.                    
  120.                    
  121.                     {
  122.                         PrefixQName qname = frame.CalulatedName;
  123.                         if (processor.BeginEvent(XPathNodeType.Element, qname.Prefix, qname.Name, qname.Namespace, this.empty) == false) {
  124.                             // Come back later
  125.                             frame.State = NameDone;
  126.                             break;
  127.                         }
  128.                        
  129.                         if (!this.empty) {
  130.                             processor.PushActionFrame(frame);
  131.                             frame.State = ProcessingChildren;
  132.                             break;
  133.                             // Allow children to run
  134.                         }
  135.                         else {
  136.                             goto case ProcessingChildren;
  137.                         }
  138.                     }
  139.                     break;
  140.                 case ProcessingChildren:
  141.                     if (processor.EndEvent(XPathNodeType.Element) == false) {
  142.                         frame.State = ProcessingChildren;
  143.                         break;
  144.                     }
  145.                     frame.Finished();
  146.                     break;
  147.                 default:
  148.                     Debug.Fail("Invalid ElementAction execution state");
  149.                     break;
  150.             }
  151.         }
  152.     }
  153. }

Developer Fusion