1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
//------------------------------------------------------------------------------
// <copyright file="ProcessingInstructionAction.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
namespace System.Xml.Xsl.XsltOld {
using Res = System.Xml.Utils.Res;
using System;
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;
internal class ProcessingInstructionAction : ContainerAction {
private const int NameEvaluated = 2;
private const int NameReady = 3;
private Avt nameAvt;
// Compile time precalculated AVT
private string name;
private const char CharX = 'X';
private const char Charx = 'x';
private const char CharM = 'M';
private const char Charm = 'm';
private const char CharL = 'L';
private const char Charl = 'l';
internal ProcessingInstructionAction() {}
internal override void Compile(Compiler compiler) {
CompileAttributes(compiler);
CheckRequiredAttribute(compiler, this.nameAvt, "name");
if(this.nameAvt.IsConstant) {
this.name = this.nameAvt.Evaluate(null, null);
this.nameAvt = null;
if (! IsProcessingInstructionName(this.name)) {
// For Now: set to null to ignore action late;
this.name = null;
}
}
if (compiler.Recurse()) {
CompileTemplate(compiler);
compiler.ToParent();
}
}
internal override bool CompileAttribute(Compiler compiler) {
string name = compiler.Input.LocalName;
string value = compiler.Input.Value;
if (Ref.Equal(name, compiler.Atoms.Name)) {
this.nameAvt = Avt.CompileAvt(compiler, value);
}
else {
return false;
}
return true;
}
internal override void Execute(Processor processor, ActionFrame frame) {
Debug.Assert(processor != null && frame != null);
switch (frame.State) {
case Initialized:
if(this.nameAvt == null) {
frame.StoredOutput = this.name;
if(this.name == null) {
// name was static but was bad;
frame.Finished();
break;
}
}
else {
frame.StoredOutput = this.nameAvt.Evaluate(processor, frame);
if (! IsProcessingInstructionName(frame.StoredOutput)) {
frame.Finished();
break;
}
}
goto case NameReady;
case NameReady:
Debug.Assert(frame.StoredOutput != null);
if (processor.BeginEvent(XPathNodeType.ProcessingInstruction, string.Empty, frame.StoredOutput, string.Empty, false) == false) {
// Come back later
frame.State = NameReady;
break;
}
processor.PushActionFrame(frame);
frame.State = ProcessingChildren;
break; // Allow children to run
case ProcessingChildren:
if (processor.EndEvent(XPathNodeType.ProcessingInstruction) == false) {
frame.State = ProcessingChildren;
break;
}
frame.Finished();
break;
default:
Debug.Fail("Invalid ElementAction execution state");
frame.Finished();
break;
}
}
internal static bool IsProcessingInstructionName(string name) {
if (name == null) {
return false;
}
int nameLength = name.Length;
int position = 0;
XmlCharType xmlCharType = XmlCharType.Instance;
while (position < nameLength && xmlCharType.IsWhiteSpace(name[position])) {
position ++;
}
if (position >= nameLength) {
return false;
}
int len = ValidateNames.ParseNCName(name, position);
if (len == 0) {
return false;
}
position += len;
while (position < nameLength && xmlCharType.IsWhiteSpace(name[position])) {
position ++;
}
if (position < nameLength) {
return false;
}
if (nameLength == 3 &&
(name[0] == CharX || name[0] == Charx) &&
(name[1] == CharM || name[1] == Charm) &&
(name[2] == CharL || name[2] == Charl)
) {
return false;
}
return true;
}
}
}
|