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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="ContainerAction.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.Text;
  21.     using System.Globalization;
  22.     using System.Xml;
  23.     using System.Xml.XPath;
  24.     using System.Xml.Xsl.Runtime;
  25.     using MS.Internal.Xml.XPath;
  26.     using System.Collections;
  27.    
  28.     internal class NamespaceInfo
  29.     {
  30.         internal string prefix;
  31.         internal string nameSpace;
  32.         internal int stylesheetId;
  33.        
  34.         internal NamespaceInfo(string prefix, string nameSpace, int stylesheetId)
  35.         {
  36.             this.prefix = prefix;
  37.             this.nameSpace = nameSpace;
  38.             this.stylesheetId = stylesheetId;
  39.         }
  40.     }
  41.    
  42.     internal class ContainerAction : CompiledAction
  43.     {
  44.         internal ArrayList containedActions;
  45.         internal CopyCodeAction lastCopyCodeAction;
  46.         // non null if last action is CopyCodeAction;
  47.         private int maxid = 0;
  48.        
  49.         // Local execution states
  50.         protected const int ProcessingChildren = 1;
  51.        
  52.         internal override void Compile(Compiler compiler)
  53.         {
  54.             throw new NotImplementedException();
  55.         }
  56.        
  57.         internal void CompileStylesheetAttributes(Compiler compiler)
  58.         {
  59.             NavigatorInput input = compiler.Input;
  60.             string element = input.LocalName;
  61.             string badAttribute = null;
  62.             string version = null;
  63.            
  64.             if (input.MoveToFirstAttribute()) {
  65.                 do {
  66.                     string nspace = input.NamespaceURI;
  67.                     string name = input.LocalName;
  68.                    
  69.                     if (!Keywords.Equals(nspace, input.Atoms.Empty))
  70.                         continue;
  71.                    
  72.                     if (Keywords.Equals(name, input.Atoms.Version)) {
  73.                         version = input.Value;
  74.                         if (1 <= XmlConvert.ToXPathDouble(version)) {
  75.                             compiler.ForwardCompatibility = (version != Keywords.s_Version10);
  76.                         }
  77.                         else {
  78.                             // XmlConvert.ToXPathDouble(version) an be NaN!
  79.                             if (!compiler.ForwardCompatibility) {
  80.                                 throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_Version, version);
  81.                             }
  82.                         }
  83.                     }
  84.                     else if (Keywords.Equals(name, input.Atoms.ExtensionElementPrefixes)) {
  85.                         compiler.InsertExtensionNamespace(input.Value);
  86.                     }
  87.                     else if (Keywords.Equals(name, input.Atoms.ExcludeResultPrefixes)) {
  88.                         compiler.InsertExcludedNamespace(input.Value);
  89.                     }
  90.                     else if (Keywords.Equals(name, input.Atoms.Id)) {
  91.                         // Do nothing here.
  92.                     }
  93.                     else {
  94.                         // We can have version atribute later. For now remember this attribute and continue
  95.                         badAttribute = name;
  96.                     }
  97.                 }
  98.                 while (input.MoveToNextAttribute());
  99.                 input.ToParent();
  100.             }
  101.            
  102.             if (version == null) {
  103.                 throw XsltException.Create(Res.Xslt_MissingAttribute, Keywords.s_Version);
  104.             }
  105.            
  106.             if (badAttribute != null && !compiler.ForwardCompatibility) {
  107.                 throw XsltException.Create(Res.Xslt_InvalidAttribute, badAttribute, element);
  108.             }
  109.         }
  110.        
  111.         internal void CompileSingleTemplate(Compiler compiler)
  112.         {
  113.             NavigatorInput input = compiler.Input;
  114.            
  115.             //
  116.             // find mandatory version attribute and launch compilation of single template
  117.             //
  118.            
  119.             string version = null;
  120.            
  121.             if (input.MoveToFirstAttribute()) {
  122.                 do {
  123.                     string nspace = input.NamespaceURI;
  124.                     string name = input.LocalName;
  125.                    
  126.                     if (Keywords.Equals(nspace, input.Atoms.XsltNamespace) && Keywords.Equals(name, input.Atoms.Version)) {
  127.                         version = input.Value;
  128.                     }
  129.                 }
  130.                 while (input.MoveToNextAttribute());
  131.                 input.ToParent();
  132.             }
  133.            
  134.             if (version == null) {
  135.                 if (Keywords.Equals(input.LocalName, input.Atoms.Stylesheet) && input.NamespaceURI == Keywords.s_WdXslNamespace) {
  136.                     throw XsltException.Create(Res.Xslt_WdXslNamespace);
  137.                 }
  138.                 throw XsltException.Create(Res.Xslt_WrongStylesheetElement);
  139.             }
  140.            
  141.             compiler.AddTemplate(compiler.CreateSingleTemplateAction());
  142.         }
  143.        
  144. /*
  145.         * CompileTopLevelElements
  146.         */       
  147.         protected void CompileDocument(Compiler compiler, bool inInclude)
  148.         {
  149.             NavigatorInput input = compiler.Input;
  150.            
  151.             // SkipToElement :
  152.             while (input.NodeType != XPathNodeType.Element) {
  153.                 if (!compiler.Advance()) {
  154.                     throw XsltException.Create(Res.Xslt_WrongStylesheetElement);
  155.                 }
  156.             }
  157.            
  158.             Debug.Assert(compiler.Input.NodeType == XPathNodeType.Element);
  159.             if (Keywords.Equals(input.NamespaceURI, input.Atoms.XsltNamespace)) {
  160.                 if (!Keywords.Equals(input.LocalName, input.Atoms.Stylesheet) && !Keywords.Equals(input.LocalName, input.Atoms.Transform)) {
  161.                     throw XsltException.Create(Res.Xslt_WrongStylesheetElement);
  162.                 }
  163.                 compiler.PushNamespaceScope();
  164.                 CompileStylesheetAttributes(compiler);
  165.                 CompileTopLevelElements(compiler);
  166.                 if (!inInclude) {
  167.                     CompileImports(compiler);
  168.                 }
  169.             }
  170.             else {
  171.                 // single template
  172.                 compiler.PushLiteralScope();
  173.                 CompileSingleTemplate(compiler);
  174.             }
  175.            
  176.             compiler.PopScope();
  177.         }
  178.        
  179.         internal Stylesheet CompileImport(Compiler compiler, Uri uri, int id)
  180.         {
  181.             NavigatorInput input = compiler.ResolveDocument(uri);
  182.             compiler.PushInputDocument(input);
  183.            
  184.             try {
  185.                 compiler.PushStylesheet(new Stylesheet());
  186.                 compiler.Stylesheetid = id;
  187.                     /*inInclude*/                CompileDocument(compiler, false);
  188.             }
  189.             catch (XsltCompileException) {
  190.                 throw;
  191.             }
  192.             catch (Exception e) {
  193.                 throw new XsltCompileException(e, input.BaseURI, input.LineNumber, input.LinePosition);
  194.             }
  195.             finally {
  196.                 compiler.PopInputDocument();
  197.             }
  198.             return compiler.PopStylesheet();
  199.         }
  200.        
  201.         private void CompileImports(Compiler compiler)
  202.         {
  203.             ArrayList imports = compiler.CompiledStylesheet.Imports;
  204.             // We can't reverce imports order. Template lookup relyes on it after compilation
  205.             int saveStylesheetId = compiler.Stylesheetid;
  206.             for (int i = imports.Count - 1; 0 <= i; i--) {
  207.                 // Imports should be compiled in reverse order
  208.                 Uri uri = imports[i] as Uri;
  209.                 Debug.Assert(uri != null);
  210.                 imports[i] = CompileImport(compiler, uri, ++this.maxid);
  211.             }
  212.             compiler.Stylesheetid = saveStylesheetId;
  213.         }
  214.        
  215.         void CompileInclude(Compiler compiler)
  216.         {
  217.             Uri uri = compiler.ResolveUri(compiler.GetSingleAttribute(compiler.Input.Atoms.Href));
  218.             string resolved = uri.ToString();
  219.             if (compiler.IsCircularReference(resolved)) {
  220.                 throw XsltException.Create(Res.Xslt_CircularInclude, resolved);
  221.             }
  222.            
  223.             NavigatorInput input = compiler.ResolveDocument(uri);
  224.             compiler.PushInputDocument(input);
  225.            
  226.             try {
  227.                     /*inInclude*/                CompileDocument(compiler, true);
  228.             }
  229.             catch (XsltCompileException) {
  230.                 throw;
  231.             }
  232.             catch (Exception e) {
  233.                 throw new XsltCompileException(e, input.BaseURI, input.LineNumber, input.LinePosition);
  234.             }
  235.             finally {
  236.                 compiler.PopInputDocument();
  237.             }
  238.             CheckEmpty(compiler);
  239.         }
  240.        
  241.         internal void CompileNamespaceAlias(Compiler compiler)
  242.         {
  243.             NavigatorInput input = compiler.Input;
  244.             string element = input.LocalName;
  245.             string namespace1 = null;
  246.             string namespace2 = null;
  247.             string prefix1 = null;
  248.             string prefix2 = null;
  249.             if (input.MoveToFirstAttribute()) {
  250.                 do {
  251.                     string nspace = input.NamespaceURI;
  252.                     string name = input.LocalName;
  253.                    
  254.                     if (!Keywords.Equals(nspace, input.Atoms.Empty))
  255.                         continue;
  256.                    
  257.                     if (Keywords.Equals(name, input.Atoms.StylesheetPrefix)) {
  258.                         prefix1 = input.Value;
  259.                         namespace1 = compiler.GetNsAlias(ref prefix1);
  260.                     }
  261.                     else if (Keywords.Equals(name, input.Atoms.ResultPrefix)) {
  262.                         prefix2 = input.Value;
  263.                         namespace2 = compiler.GetNsAlias(ref prefix2);
  264.                     }
  265.                     else {
  266.                         if (!compiler.ForwardCompatibility) {
  267.                             throw XsltException.Create(Res.Xslt_InvalidAttribute, name, element);
  268.                         }
  269.                     }
  270.                 }
  271.                 while (input.MoveToNextAttribute());
  272.                 input.ToParent();
  273.             }
  274.            
  275.             CheckRequiredAttribute(compiler, namespace1, Keywords.s_StylesheetPrefix);
  276.             CheckRequiredAttribute(compiler, namespace2, Keywords.s_ResultPrefix);
  277.             CheckEmpty(compiler);
  278.            
  279.             //String[] resultarray = { prefix2, namespace2 };
  280.             compiler.AddNamespaceAlias(namespace1, new NamespaceInfo(prefix2, namespace2, compiler.Stylesheetid));
  281.         }
  282.        
  283.         internal void CompileKey(Compiler compiler)
  284.         {
  285.             NavigatorInput input = compiler.Input;
  286.             string element = input.LocalName;
  287.             int MatchKey = Compiler.InvalidQueryKey;
  288.             int UseKey = Compiler.InvalidQueryKey;
  289.            
  290.             XmlQualifiedName Name = null;
  291.             if (input.MoveToFirstAttribute()) {
  292.                 do {
  293.                     string nspace = input.NamespaceURI;
  294.                     string name = input.LocalName;
  295.                     string value = input.Value;
  296.                    
  297.                     if (!Keywords.Equals(nspace, input.Atoms.Empty))
  298.                         continue;
  299.                    
  300.                     if (Keywords.Equals(name, input.Atoms.Name)) {
  301.                         Name = compiler.CreateXPathQName(value);
  302.                     }
  303.                     else if (Keywords.Equals(name, input.Atoms.Match)) {
  304.                             /*allowVars:*/                            /*allowKey*/                            /*pattern*/                        MatchKey = compiler.AddQuery(value, false, false, true);
  305.                     }
  306.                     else if (Keywords.Equals(name, input.Atoms.Use)) {
  307.                             /*allowVars:*/                            /*allowKey*/                            /*pattern*/                        UseKey = compiler.AddQuery(value, false, false, false);
  308.                     }
  309.                     else {
  310.                         if (!compiler.ForwardCompatibility) {
  311.                             throw XsltException.Create(Res.Xslt_InvalidAttribute, name, element);
  312.                         }
  313.                     }
  314.                 }
  315.                 while (input.MoveToNextAttribute());
  316.                 input.ToParent();
  317.             }
  318.            
  319.             CheckRequiredAttribute(compiler, MatchKey != Compiler.InvalidQueryKey, Keywords.s_Match);
  320.             CheckRequiredAttribute(compiler, UseKey != Compiler.InvalidQueryKey, Keywords.s_Use);
  321.             CheckRequiredAttribute(compiler, Name != null, Keywords.s_Name);
  322.            
  323.             compiler.InsertKey(Name, MatchKey, UseKey);
  324.         }
  325.        
  326.         protected void CompileDecimalFormat(Compiler compiler)
  327.         {
  328.             NumberFormatInfo info = new NumberFormatInfo();
  329.             DecimalFormat format = new DecimalFormat(info, '#', '0', ';');
  330.             XmlQualifiedName Name = null;
  331.             NavigatorInput input = compiler.Input;
  332.             if (input.MoveToFirstAttribute()) {
  333.                 do {
  334.                     if (!Keywords.Equals(input.Prefix, input.Atoms.Empty))
  335.                         continue;
  336.                    
  337.                     string name = input.LocalName;
  338.                     string value = input.Value;
  339.                    
  340.                     if (Keywords.Equals(name, input.Atoms.Name)) {
  341.                         Name = compiler.CreateXPathQName(value);
  342.                     }
  343.                     else if (Keywords.Equals(name, input.Atoms.DecimalSeparator)) {
  344.                         info.NumberDecimalSeparator = value;
  345.                     }
  346.                     else if (Keywords.Equals(name, input.Atoms.GroupingSeparator)) {
  347.                         info.NumberGroupSeparator = value;
  348.                     }
  349.                     else if (Keywords.Equals(name, input.Atoms.Infinity)) {
  350.                         info.PositiveInfinitySymbol = value;
  351.                     }
  352.                     else if (Keywords.Equals(name, input.Atoms.MinusSign)) {
  353.                         info.NegativeSign = value;
  354.                     }
  355.                     else if (Keywords.Equals(name, input.Atoms.NaN)) {
  356.                         info.NaNSymbol = value;
  357.                     }
  358.                     else if (Keywords.Equals(name, input.Atoms.Percent)) {
  359.                         info.PercentSymbol = value;
  360.                     }
  361.                     else if (Keywords.Equals(name, input.Atoms.PerMille)) {
  362.                         info.PerMilleSymbol = value;
  363.                     }
  364.                     else if (Keywords.Equals(name, input.Atoms.Digit)) {
  365.                         if (CheckAttribute(value.Length == 1, compiler)) {
  366.                             format.digit = value[0];
  367.                         }
  368.                     }
  369.                     else if (Keywords.Equals(name, input.Atoms.ZeroDigit)) {
  370.                         if (CheckAttribute(value.Length == 1, compiler)) {
  371.                             format.zeroDigit = value[0];
  372.                         }
  373.                     }
  374.                     else if (Keywords.Equals(name, input.Atoms.PatternSeparator)) {
  375.                         if (CheckAttribute(value.Length == 1, compiler)) {
  376.                             format.patternSeparator = value[0];
  377.                         }
  378.                     }
  379.                 }
  380.                 while (input.MoveToNextAttribute());
  381.                 input.ToParent();
  382.             }
  383.             info.NegativeInfinitySymbol = String.Concat(info.NegativeSign, info.PositiveInfinitySymbol);
  384.             if (Name == null) {
  385.                 Name = new XmlQualifiedName();
  386.             }
  387.             compiler.AddDecimalFormat(Name, format);
  388.             CheckEmpty(compiler);
  389.         }
  390.        
  391.         internal bool CheckAttribute(bool valid, Compiler compiler)
  392.         {
  393.             if (!valid) {
  394.                 if (!compiler.ForwardCompatibility) {
  395.                     throw XsltException.Create(Res.Xslt_InvalidAttrValue, compiler.Input.LocalName, compiler.Input.Value);
  396.                 }
  397.                 return false;
  398.             }
  399.             return true;
  400.         }
  401.        
  402.         protected void CompileSpace(Compiler compiler, bool preserve)
  403.         {
  404.             string value = compiler.GetSingleAttribute(compiler.Input.Atoms.Elements);
  405.             string[] elements = XmlConvert.SplitString(value);
  406.             for (int i = 0; i < elements.Length; i++) {
  407.                 double defaultPriority = NameTest(elements[i]);
  408.                 compiler.CompiledStylesheet.AddSpace(compiler, elements[i], defaultPriority, preserve);
  409.             }
  410.             CheckEmpty(compiler);
  411.         }
  412.        
  413.         double NameTest(string name)
  414.         {
  415.             if (name == "*") {
  416.                 return -0.5;
  417.             }
  418.             int idx = name.Length - 2;
  419.             if (0 <= idx && name[idx] == ':' && name[idx + 1] == '*') {
  420.                 if (!PrefixQName.ValidatePrefix(name.Substring(0, idx))) {
  421.                     throw XsltException.Create(Res.Xslt_InvalidAttrValue, Keywords.s_Elements, name);
  422.                 }
  423.                 return -0.25;
  424.             }
  425.             else {
  426.                 string prefix;
  427.                 string localname;
  428.                 PrefixQName.ParseQualifiedName(name, out prefix, out localname);
  429.                 return 0;
  430.             }
  431.         }
  432.        
  433.         protected void CompileTopLevelElements(Compiler compiler)
  434.         {
  435.             // Navigator positioned at parent root, need to move to child and then back
  436.             if (compiler.Recurse() == false) {
  437.                 return;
  438.             }
  439.            
  440.             NavigatorInput input = compiler.Input;
  441.             bool notFirstElement = false;
  442.             do {
  443.                 switch (input.NodeType) {
  444.                     case XPathNodeType.Element:
  445.                         string name = input.LocalName;
  446.                         string nspace = input.NamespaceURI;
  447.                        
  448.                         if (Keywords.Equals(nspace, input.Atoms.XsltNamespace)) {
  449.                             if (Keywords.Equals(name, input.Atoms.Import)) {
  450.                                 if (notFirstElement) {
  451.                                     throw XsltException.Create(Res.Xslt_NotFirstImport);
  452.                                 }
  453.                                 // We should compile imports in reverse order after all toplevel elements.
  454.                                 // remember it now and return to it in CompileImpoorts();
  455.                                 Uri uri = compiler.ResolveUri(compiler.GetSingleAttribute(compiler.Input.Atoms.Href));
  456.                                 string resolved = uri.ToString();
  457.                                 if (compiler.IsCircularReference(resolved)) {
  458.                                     throw XsltException.Create(Res.Xslt_CircularInclude, resolved);
  459.                                 }
  460.                                 compiler.CompiledStylesheet.Imports.Add(uri);
  461.                                 CheckEmpty(compiler);
  462.                             }
  463.                             else if (Keywords.Equals(name, input.Atoms.Include)) {
  464.                                 notFirstElement = true;
  465.                                 CompileInclude(compiler);
  466.                             }
  467.                             else {
  468.                                 notFirstElement = true;
  469.                                 compiler.PushNamespaceScope();
  470.                                 if (Keywords.Equals(name, input.Atoms.StripSpace)) {
  471.                                     CompileSpace(compiler, false);
  472.                                 }
  473.                                 else if (Keywords.Equals(name, input.Atoms.PreserveSpace)) {
  474.                                     CompileSpace(compiler, true);
  475.                                 }
  476.                                 else if (Keywords.Equals(name, input.Atoms.Output)) {
  477.                                     CompileOutput(compiler);
  478.                                 }
  479.                                 else if (Keywords.Equals(name, input.Atoms.Key)) {
  480.                                     CompileKey(compiler);
  481.                                 }
  482.                                 else if (Keywords.Equals(name, input.Atoms.DecimalFormat)) {
  483.                                     CompileDecimalFormat(compiler);
  484.                                 }
  485.                                 else if (Keywords.Equals(name, input.Atoms.NamespaceAlias)) {
  486.                                     CompileNamespaceAlias(compiler);
  487.                                 }
  488.                                 else if (Keywords.Equals(name, input.Atoms.AttributeSet)) {
  489.                                     compiler.AddAttributeSet(compiler.CreateAttributeSetAction());
  490.                                 }
  491.                                 else if (Keywords.Equals(name, input.Atoms.Variable)) {
  492.                                     VariableAction action = compiler.CreateVariableAction(VariableType.GlobalVariable);
  493.                                     if (action != null) {
  494.                                         AddAction(action);
  495.                                     }
  496.                                 }
  497.                                 else if (Keywords.Equals(name, input.Atoms.Param)) {
  498.                                     VariableAction action = compiler.CreateVariableAction(VariableType.GlobalParameter);
  499.                                     if (action != null) {
  500.                                         AddAction(action);
  501.                                     }
  502.                                 }
  503.                                 else if (Keywords.Equals(name, input.Atoms.Template)) {
  504.                                     compiler.AddTemplate(compiler.CreateTemplateAction());
  505.                                 }
  506.                                 else {
  507.                                     if (!compiler.ForwardCompatibility) {
  508.                                         throw compiler.UnexpectedKeyword();
  509.                                     }
  510.                                 }
  511.                                 compiler.PopScope();
  512.                             }
  513.                         }
  514.                         else if (nspace == input.Atoms.MsXsltNamespace && name == input.Atoms.Script) {
  515.                             AddScript(compiler);
  516.                         }
  517.                         else {
  518.                             if (Keywords.Equals(nspace, input.Atoms.Empty)) {
  519.                                 throw XsltException.Create(Res.Xslt_NullNsAtTopLevel, input.Name);
  520.                             }
  521.                             // Ignoring non-recognized namespace per XSLT spec 2.2
  522.                         }
  523.                         break;
  524.                     case XPathNodeType.ProcessingInstruction:
  525.                     case XPathNodeType.Comment:
  526.                     case XPathNodeType.Whitespace:
  527.                     case XPathNodeType.SignificantWhitespace:
  528.                        
  529.                         break;
  530.                     default:
  531.                        
  532.                         throw XsltException.Create(Res.Xslt_InvalidContents, Keywords.s_Stylesheet);
  533.                         break;
  534.                 }
  535.             }
  536.             while (compiler.Advance());
  537.            
  538.             compiler.ToParent();
  539.         }
  540.        
  541.         protected void CompileTemplate(Compiler compiler)
  542.         {
  543.             do {
  544.                 CompileOnceTemplate(compiler);
  545.             }
  546.             while (compiler.Advance());
  547.         }
  548.        
  549.         protected void CompileOnceTemplate(Compiler compiler)
  550.         {
  551.             NavigatorInput input = compiler.Input;
  552.            
  553.             if (input.NodeType == XPathNodeType.Element) {
  554.                 string nspace = input.NamespaceURI;
  555.                
  556.                 if (Keywords.Equals(nspace, input.Atoms.XsltNamespace)) {
  557.                     compiler.PushNamespaceScope();
  558.                     CompileInstruction(compiler);
  559.                     compiler.PopScope();
  560.                 }
  561.                 else {
  562.                     compiler.PushLiteralScope();
  563.                     compiler.InsertExtensionNamespace();
  564.                     if (compiler.IsExtensionNamespace(nspace)) {
  565.                         AddAction(compiler.CreateNewInstructionAction());
  566.                     }
  567.                     else {
  568.                         CompileLiteral(compiler);
  569.                     }
  570.                     compiler.PopScope();
  571.                 }
  572.             }
  573.             else {
  574.                 CompileLiteral(compiler);
  575.             }
  576.         }
  577.        
  578.         void CompileInstruction(Compiler compiler)
  579.         {
  580.             NavigatorInput input = compiler.Input;
  581.             CompiledAction action = null;
  582.            
  583.             Debug.Assert(Keywords.Equals(input.NamespaceURI, input.Atoms.XsltNamespace));
  584.            
  585.             string name = input.LocalName;
  586.            
  587.             if (Keywords.Equals(name, input.Atoms.ApplyImports)) {
  588.                 action = compiler.CreateApplyImportsAction();
  589.             }
  590.             else if (Keywords.Equals(name, input.Atoms.ApplyTemplates)) {
  591.                 action = compiler.CreateApplyTemplatesAction();
  592.             }
  593.             else if (Keywords.Equals(name, input.Atoms.Attribute)) {
  594.                 action = compiler.CreateAttributeAction();
  595.             }
  596.             else if (Keywords.Equals(name, input.Atoms.CallTemplate)) {
  597.                 action = compiler.CreateCallTemplateAction();
  598.             }
  599.             else if (Keywords.Equals(name, input.Atoms.Choose)) {
  600.                 action = compiler.CreateChooseAction();
  601.             }
  602.             else if (Keywords.Equals(name, input.Atoms.Comment)) {
  603.                 action = compiler.CreateCommentAction();
  604.             }
  605.             else if (Keywords.Equals(name, input.Atoms.Copy)) {
  606.                 action = compiler.CreateCopyAction();
  607.             }
  608.             else if (Keywords.Equals(name, input.Atoms.CopyOf)) {
  609.                 action = compiler.CreateCopyOfAction();
  610.             }
  611.             else if (Keywords.Equals(name, input.Atoms.Element)) {
  612.                 action = compiler.CreateElementAction();
  613.             }
  614.             else if (Keywords.Equals(name, input.Atoms.Fallback)) {
  615.                 return;
  616.             }
  617.             else if (Keywords.Equals(name, input.Atoms.ForEach)) {
  618.                 action = compiler.CreateForEachAction();
  619.             }
  620.             else if (Keywords.Equals(name, input.Atoms.If)) {
  621.                 action = compiler.CreateIfAction(IfAction.ConditionType.ConditionIf);
  622.             }
  623.             else if (Keywords.Equals(name, input.Atoms.Message)) {
  624.                 action = compiler.CreateMessageAction();
  625.             }
  626.             else if (Keywords.Equals(name, input.Atoms.Number)) {
  627.                 action = compiler.CreateNumberAction();
  628.             }
  629.             else if (Keywords.Equals(name, input.Atoms.ProcessingInstruction)) {
  630.                 action = compiler.CreateProcessingInstructionAction();
  631.             }
  632.             else if (Keywords.Equals(name, input.Atoms.Text)) {
  633.                 action = compiler.CreateTextAction();
  634.             }
  635.             else if (Keywords.Equals(name, input.Atoms.ValueOf)) {
  636.                 action = compiler.CreateValueOfAction();
  637.             }
  638.             else if (Keywords.Equals(name, input.Atoms.Variable)) {
  639.                 action = compiler.CreateVariableAction(VariableType.LocalVariable);
  640.             }
  641.             else {
  642.                 if (compiler.ForwardCompatibility)
  643.                     action = compiler.CreateNewInstructionAction();
  644.                 else
  645.                     throw compiler.UnexpectedKeyword();
  646.             }
  647.            
  648.             Debug.Assert(action != null);
  649.            
  650.             AddAction(action);
  651.         }
  652.        
  653.         void CompileLiteral(Compiler compiler)
  654.         {
  655.             NavigatorInput input = compiler.Input;
  656.            
  657.             switch (input.NodeType) {
  658.                 case XPathNodeType.Element:
  659.                     this.AddEvent(compiler.CreateBeginEvent());
  660.                     CompileLiteralAttributesAndNamespaces(compiler);
  661.                    
  662.                     if (compiler.Recurse()) {
  663.                         CompileTemplate(compiler);
  664.                         compiler.ToParent();
  665.                     }
  666.                    
  667.                     this.AddEvent(new EndEvent(XPathNodeType.Element));
  668.                     break;
  669.                 case XPathNodeType.Text:
  670.                 case XPathNodeType.SignificantWhitespace:
  671.                    
  672.                     this.AddEvent(compiler.CreateTextEvent());
  673.                     break;
  674.                 case XPathNodeType.Whitespace:
  675.                 case XPathNodeType.ProcessingInstruction:
  676.                 case XPathNodeType.Comment:
  677.                     break;
  678.                 default:
  679.                    
  680.                     Debug.Assert(false, "Unexpected node type.");
  681.                     break;
  682.             }
  683.         }
  684.        
  685.         void CompileLiteralAttributesAndNamespaces(Compiler compiler)
  686.         {
  687.             NavigatorInput input = compiler.Input;
  688.            
  689.             if (input.Navigator.MoveToAttribute(Keywords.s_UseAttributeSets, input.Atoms.XsltNamespace)) {
  690.                 AddAction(compiler.CreateUseAttributeSetsAction());
  691.                 input.Navigator.MoveToParent();
  692.             }
  693.             compiler.InsertExcludedNamespace();
  694.            
  695.             if (input.MoveToFirstNamespace()) {
  696.                 do {
  697.                     string uri = input.Value;
  698.                    
  699.                     if (Keywords.Compare(uri, input.Atoms.XsltNamespace)) {
  700.                         continue;
  701.                     }
  702.                     if (compiler.IsExcludedNamespace(uri) || compiler.IsExtensionNamespace(uri) || compiler.IsNamespaceAlias(uri)) {
  703.                         continue;
  704.                     }
  705.                     this.AddEvent(new NamespaceEvent(input));
  706.                 }
  707.                 while (input.MoveToNextNamespace());
  708.                 input.ToParent();
  709.             }
  710.            
  711.             if (input.MoveToFirstAttribute()) {
  712.                 do {
  713.                    
  714.                     // Skip everything from Xslt namespace
  715.                     if (Keywords.Equals(input.NamespaceURI, input.Atoms.XsltNamespace)) {
  716.                         continue;
  717.                     }
  718.                    
  719.                     // Add attribute events
  720.                     this.AddEvent(compiler.CreateBeginEvent());
  721.                     this.AddEvents(compiler.CompileAvt(input.Value));
  722.                     this.AddEvent(new EndEvent(XPathNodeType.Attribute));
  723.                 }
  724.                 while (input.MoveToNextAttribute());
  725.                 input.ToParent();
  726.             }
  727.         }
  728.        
  729.         void CompileOutput(Compiler compiler)
  730.         {
  731.             Debug.Assert((object)this == (object)compiler.RootAction);
  732.             compiler.RootAction.Output.Compile(compiler);
  733.         }
  734.        
  735.         internal void AddAction(Action action)
  736.         {
  737.             if (this.containedActions == null) {
  738.                 this.containedActions = new ArrayList();
  739.             }
  740.             this.containedActions.Add(action);
  741.             lastCopyCodeAction = null;
  742.         }
  743.        
  744.         private void EnsureCopyCodeAction()
  745.         {
  746.             if (lastCopyCodeAction == null) {
  747.                 CopyCodeAction copyCode = new CopyCodeAction();
  748.                 AddAction(copyCode);
  749.                 lastCopyCodeAction = copyCode;
  750.             }
  751.         }
  752.        
  753.         protected void AddEvent(Event copyEvent)
  754.         {
  755.             EnsureCopyCodeAction();
  756.             lastCopyCodeAction.AddEvent(copyEvent);
  757.         }
  758.        
  759.         protected void AddEvents(ArrayList copyEvents)
  760.         {
  761.             EnsureCopyCodeAction();
  762.             lastCopyCodeAction.AddEvents(copyEvents);
  763.         }
  764.        
  765.         private void AddScript(Compiler compiler)
  766.         {
  767.             NavigatorInput input = compiler.Input;
  768.            
  769.             ScriptingLanguage lang = ScriptingLanguage.JScript;
  770.             string implementsNamespace = null;
  771.             if (input.MoveToFirstAttribute()) {
  772.                 do {
  773.                     if (input.LocalName == input.Atoms.Language) {
  774.                         string langName = input.Value;
  775.                         if (String.Compare(langName, "jscript", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(langName, "javascript", StringComparison.OrdinalIgnoreCase) == 0) {
  776.                             lang = ScriptingLanguage.JScript;
  777.                         }
  778.                         else if (String.Compare(langName, "c#", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(langName, "csharp", StringComparison.OrdinalIgnoreCase) == 0) {
  779.                             lang = ScriptingLanguage.CSharp;
  780.                         }
  781.                         else {
  782.                             throw XsltException.Create(Res.Xslt_ScriptInvalidLanguage, langName);
  783.                         }
  784.                     }
  785.                     else if (input.LocalName == input.Atoms.ImplementsPrefix) {
  786.                         if (!PrefixQName.ValidatePrefix(input.Value)) {
  787.                             throw XsltException.Create(Res.Xslt_InvalidAttrValue, input.LocalName, input.Value);
  788.                         }
  789.                         implementsNamespace = compiler.ResolveXmlNamespace(input.Value);
  790.                     }
  791.                 }
  792.                 while (input.MoveToNextAttribute());
  793.                 input.ToParent();
  794.             }
  795.             if (implementsNamespace == null) {
  796.                 throw XsltException.Create(Res.Xslt_MissingAttribute, input.Atoms.ImplementsPrefix);
  797.             }
  798.             if (!input.Recurse() || input.NodeType != XPathNodeType.Text) {
  799.                 throw XsltException.Create(Res.Xslt_ScriptEmpty);
  800.             }
  801.             compiler.AddScript(input.Value, lang, implementsNamespace, input.BaseURI, input.LineNumber);
  802.             input.ToParent();
  803.         }
  804.        
  805.         internal override void Execute(Processor processor, ActionFrame frame)
  806.         {
  807.             Debug.Assert(processor != null && frame != null);
  808.            
  809.             switch (frame.State) {
  810.                 case Initialized:
  811.                     if (this.containedActions != null && this.containedActions.Count > 0) {
  812.                         processor.PushActionFrame(frame);
  813.                         frame.State = ProcessingChildren;
  814.                     }
  815.                     else {
  816.                         frame.Finished();
  817.                     }
  818.                     break;
  819.                 case ProcessingChildren:
  820.                     // Allow children to run
  821.                     frame.Finished();
  822.                     break;
  823.                 default:
  824.                    
  825.                     Debug.Fail("Invalid Container action execution state");
  826.                     break;
  827.             }
  828.         }
  829.        
  830.         internal Action GetAction(int actionIndex)
  831.         {
  832.             Debug.Assert(actionIndex == 0 || this.containedActions != null);
  833.            
  834.             if (this.containedActions != null && actionIndex < this.containedActions.Count) {
  835.                 return (Action)this.containedActions[actionIndex];
  836.             }
  837.             else {
  838.                 return null;
  839.             }
  840.         }
  841.        
  842.         internal void CheckDuplicateParams(XmlQualifiedName name)
  843.         {
  844.             if (this.containedActions != null) {
  845.                 foreach (CompiledAction action in this.containedActions) {
  846.                     WithParamAction param = action as WithParamAction;
  847.                     if (param != null && param.Name == name) {
  848.                         throw XsltException.Create(Res.Xslt_DuplicateWithParam, name.ToString());
  849.                     }
  850.                 }
  851.             }
  852.         }
  853.        
  854.         internal override void ReplaceNamespaceAlias(Compiler compiler)
  855.         {
  856.             if (this.containedActions == null) {
  857.                 return;
  858.             }
  859.             int count = this.containedActions.Count;
  860.             for (int i = 0; i < this.containedActions.Count; i++) {
  861.                 ((Action)this.containedActions[i]).ReplaceNamespaceAlias(compiler);
  862.             }
  863.         }
  864.     }
  865. }

Developer Fusion