1 //------------------------------------------------------------------------------
2 // <copyright file="ElementAction.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
8 namespace System.Xml.Xsl.XsltOld {
9 using Res = System.Xml.Utils.Res;
11 using System.Diagnostics;
13 using System.Xml.XPath;
15 internal class ElementAction : ContainerAction {
16 private const int NameDone = 2;
21 private InputScopeManager manager;
22 // Compile time precalculated AVTs
25 private PrefixQName qname; // When we not have AVTs at all we can do this. null otherwise.
27 internal ElementAction() {}
29 private static PrefixQName CreateElementQName(string name, string nsUri, InputScopeManager manager) {
30 if (nsUri == XmlReservedNs.NsXmlNs) {
31 throw XsltException.Create(Res.Xslt_ReservedNS, nsUri);
34 PrefixQName qname = new PrefixQName();
38 qname.Namespace = manager.ResolveXmlNamespace(qname.Prefix);
41 qname.Namespace = nsUri;
46 internal override void Compile(Compiler compiler) {
47 CompileAttributes(compiler);
48 CheckRequiredAttribute(compiler, this.nameAvt, "name");
50 this.name = PrecalculateAvt(ref this.nameAvt);
51 this.nsUri = PrecalculateAvt(ref this.nsAvt );
53 // if both name and ns are not AVT we can calculate qname at compile time and will not need namespace manager anymore
54 if (this.nameAvt == null && this.nsAvt == null) {
55 if(this.name != "xmlns") {
56 this.qname = CreateElementQName(this.name, this.nsUri, compiler.CloneScopeManager());
60 this.manager = compiler.CloneScopeManager();
63 if (compiler.Recurse()) {
64 Debug.Assert(this.empty == false);
65 CompileTemplate(compiler);
68 this.empty = (this.containedActions == null) ;
71 internal override bool CompileAttribute(Compiler compiler) {
72 string name = compiler.Input.LocalName;
73 string value = compiler.Input.Value;
74 if (Ref.Equal(name, compiler.Atoms.Name)) {
75 this.nameAvt = Avt.CompileAvt(compiler, value);
77 else if (Ref.Equal(name, compiler.Atoms.Namespace)) {
78 this.nsAvt = Avt.CompileAvt(compiler, value);
80 else if (Ref.Equal(name, compiler.Atoms.UseAttributeSets)) {
81 AddAction(compiler.CreateUseAttributeSetsAction());
90 internal override void Execute(Processor processor, ActionFrame frame) {
91 Debug.Assert(processor != null && frame != null);
93 switch (frame.State) {
95 if(this.qname != null) {
96 frame.CalulatedName = this.qname;
99 frame.CalulatedName = CreateElementQName(
100 this.nameAvt == null ? this.name : this.nameAvt.Evaluate(processor, frame),
101 this.nsAvt == null ? this.nsUri : this.nsAvt .Evaluate(processor, frame),
109 PrefixQName qname = frame.CalulatedName;
110 if (processor.BeginEvent(XPathNodeType.Element, qname.Prefix, qname.Name, qname.Namespace, this.empty) == false) {
112 frame.State = NameDone;
117 processor.PushActionFrame(frame);
118 frame.State = ProcessingChildren;
119 break; // Allow children to run
122 goto case ProcessingChildren;
125 case ProcessingChildren:
126 if (processor.EndEvent(XPathNodeType.Element) == false) {
127 frame.State = ProcessingChildren;
133 Debug.Fail("Invalid ElementAction execution state");