Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / XmlUtils / System / Xml / Xsl / XsltOld / RecordBuilder.cs / 1 / RecordBuilder.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.XsltOld { using Res = System.Xml.Utils.Res; using System; using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.XPath; using System.Collections; internal sealed class RecordBuilder { private int outputState; private RecordBuilder next; RecordOutput output; // Atomization: private XmlNameTable nameTable; private OutKeywords atoms; // Namespace manager for output private OutputScopeManager scopeManager; // Main node + Fields Collection private BuilderInfo mainNode = new BuilderInfo(); private ArrayList attributeList = new ArrayList(); private int attributeCount; private ArrayList namespaceList = new ArrayList(); private int namespaceCount; private BuilderInfo dummy = new BuilderInfo(); // Current position in the list private BuilderInfo currentInfo; // Builder state private bool popScope; private int recordState; private int recordDepth; private const int NoRecord = 0; // No part of a new record was generated (old record was cleared out) private const int SomeRecord = 1; // Record was generated partially (can be eventually record) private const int HaveRecord = 2; // Record was fully generated private const char s_Minus = '-'; private const string s_Space = " "; private const string s_SpaceMinus = " -"; private const char s_Question = '?'; private const char s_Greater = '>'; private const string s_SpaceGreater = " >"; private const string PrefixFormat = "xp_{0}"; private const string s_SpaceDefault = "default"; private const string s_SpacePreserve = "preserve"; internal RecordBuilder(RecordOutput output, XmlNameTable nameTable) { Debug.Assert(output != null); this.output = output; this.nameTable = nameTable != null ? nameTable : new NameTable(); this.atoms = new OutKeywords(this.nameTable); this.scopeManager = new OutputScopeManager(this.nameTable, this.atoms); } // // Internal properties // internal int OutputState { get { return this.outputState; } set { this.outputState = value; } } internal RecordBuilder Next { get { return this.next; } set { this.next = value; } } internal RecordOutput Output { get { return this.output; } } internal BuilderInfo MainNode { get { return this.mainNode; } } internal ArrayList AttributeList { get { return this.attributeList; } } internal int AttributeCount { get { return this.attributeCount; } } internal OutputScopeManager Manager { get { return this.scopeManager; } } private void ValueAppend(string s, bool disableOutputEscaping) { this.currentInfo.ValueAppend(s, disableOutputEscaping); } private bool CanOutput(int state) { Debug.Assert(this.recordState != HaveRecord); // If we have no record cached or the next event doesn't start new record, we are OK if (this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0) { return true; } else { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this) == Processor.OutputResult.Continue; } } internal Processor.OutputResult BeginEvent(int state, XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); prefix = (prefix != null) ? this.nameTable.Add(prefix) : this.atoms.Empty; name = (name != null) ? this.nameTable.Add(name) : this.atoms.Empty; nspace = (nspace != null) ? this.nameTable.Add(nspace) : this.atoms.Empty; switch (nodeType) { case XPathNodeType.Element: this.mainNode.htmlProps = htmlProps as HtmlElementProps; this.mainNode.search = search; BeginElement(prefix, name, nspace, empty); break; case XPathNodeType.Attribute: BeginAttribute(prefix, name, nspace, htmlProps, search); break; case XPathNodeType.Namespace: BeginNamespace(name, nspace); break; case XPathNodeType.Text: break; case XPathNodeType.ProcessingInstruction: if (BeginProcessingInstruction(prefix, name, nspace) == false) { return Processor.OutputResult.Error; } break; case XPathNodeType.Comment: BeginComment(); break; case XPathNodeType.Root: break; case XPathNodeType.Whitespace: case XPathNodeType.SignificantWhitespace: case XPathNodeType.All: break; } return CheckRecordBegin(state); } internal Processor.OutputResult TextEvent(int state, string text, bool disableOutputEscaping) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); if ((state & StateMachine.BeginRecord) != 0) { this.currentInfo.Depth = this.recordDepth; this.currentInfo.NodeType = XmlNodeType.Text; } ValueAppend(text, disableOutputEscaping); return CheckRecordBegin(state); } internal Processor.OutputResult EndEvent(int state, XPathNodeType nodeType) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } AdjustDepth(state); PopElementScope(); this.popScope = (state & StateMachine.PopScope) != 0; if ((state & StateMachine.EmptyTag) != 0 && this.mainNode.IsEmptyTag == true) { return Processor.OutputResult.Continue; } ResetRecord(state); if ((state & StateMachine.BeginRecord) != 0) { if(nodeType == XPathNodeType.Element) { EndElement(); } } return CheckRecordEnd(state); } internal void Reset() { if (this.recordState == HaveRecord) { this.recordState = NoRecord; } } internal void TheEnd() { if (this.recordState == SomeRecord) { this.recordState = HaveRecord; FinalizeRecord(); this.output.RecordDone(this); } this.output.TheEnd(); } // // Utility implementation methods // private int FindAttribute(string name, string nspace, ref string prefix) { Debug.Assert(this.attributeCount <= this.attributeList.Count); for (int attrib = 0; attrib < this.attributeCount; attrib ++) { Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; if (Keywords.Equals(attribute.LocalName, name)) { if (Keywords.Equals(attribute.NamespaceURI, nspace)) { return attrib; } if (Keywords.Equals(attribute.Prefix, prefix)) { // prefix conflict. Should be renamed. prefix = string.Empty; } } } return -1; } private void BeginElement(string prefix, string name, string nspace, bool empty) { Debug.Assert(this.attributeCount == 0); this.currentInfo.NodeType = XmlNodeType.Element; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; this.currentInfo.IsEmptyTag = empty; this.scopeManager.PushScope(name, nspace, prefix); } private void EndElement() { Debug.Assert(this.attributeCount == 0); OutputScope elementScope = this.scopeManager.CurrentElementScope; this.currentInfo.NodeType = XmlNodeType.EndElement; this.currentInfo.Prefix = elementScope.Prefix; this.currentInfo.LocalName = elementScope.Name; this.currentInfo.NamespaceURI = elementScope.Namespace; this.currentInfo.Depth = this.recordDepth; } private int NewAttribute() { if (this.attributeCount >= this.attributeList.Count) { Debug.Assert(this.attributeCount == this.attributeList.Count); this.attributeList.Add(new BuilderInfo()); } return this.attributeCount ++; } private void BeginAttribute(string prefix, string name, string nspace, Object htmlAttrProps, bool search) { int attrib = FindAttribute(name, nspace, ref prefix); if (attrib == -1) { attrib = NewAttribute(); } Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; attribute.Initialize(prefix, name, nspace); attribute.Depth = this.recordDepth; attribute.NodeType = XmlNodeType.Attribute; attribute.htmlAttrProps = htmlAttrProps as HtmlAttributeProps; attribute.search = search; this.currentInfo = attribute; } private void BeginNamespace(string name, string nspace) { bool thisScope = false; if (Keywords.Equals(name, this.atoms.Empty)) { if (Keywords.Equals(nspace, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { // http://www.w3.org/1999/11/REC-xslt-19991116-errata/ E25 // Should throw an error but ingnoring it in Everett. // Would be a breaking change } else { DeclareNamespace(nspace, name); } } else { string nspaceDeclared = this.scopeManager.ResolveNamespace(name, out thisScope); if (nspaceDeclared != null) { if (! Keywords.Equals(nspace, nspaceDeclared)) { if(!thisScope) { DeclareNamespace(nspace, name); } } } else { DeclareNamespace(nspace, name); } } this.currentInfo = dummy; currentInfo.NodeType = XmlNodeType.Attribute; } private bool BeginProcessingInstruction(string prefix, string name, string nspace) { this.currentInfo.NodeType = XmlNodeType.ProcessingInstruction; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; return true; } private void BeginComment() { this.currentInfo.NodeType = XmlNodeType.Comment; this.currentInfo.Depth = this.recordDepth; } private void AdjustDepth(int state) { switch (state & StateMachine.DepthMask) { case StateMachine.DepthUp: this.recordDepth ++; break; case StateMachine.DepthDown: this.recordDepth --; break; default: break; } } private void ResetRecord(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.BeginRecord) != 0) { this.attributeCount = 0; this.namespaceCount = 0; this.currentInfo = this.mainNode; this.currentInfo.Initialize(this.atoms.Empty, this.atoms.Empty, this.atoms.Empty); this.currentInfo.NodeType = XmlNodeType.None; this.currentInfo.IsEmptyTag = false; this.currentInfo.htmlProps = null; this.currentInfo.htmlAttrProps = null; } } private void PopElementScope() { if (this.popScope) { this.scopeManager.PopScope(); this.popScope = false; } } private Processor.OutputResult CheckRecordBegin(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { this.recordState = SomeRecord; return Processor.OutputResult.Continue; } } private Processor.OutputResult CheckRecordEnd(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { // For end event, if there is no end token, don't force token return Processor.OutputResult.Continue; } } private void SetEmptyFlag(int state) { Debug.Assert(this.mainNode != null); if ((state & StateMachine.BeginChild) != 0) { this.mainNode.IsEmptyTag = false; } } private void AnalyzeSpaceLang() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); for (int attr = 0; attr < this.attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.Prefix, this.atoms.Xml)) { OutputScope scope = this.scopeManager.CurrentElementScope; if (Keywords.Equals(info.LocalName, this.atoms.Lang)) { scope.Lang = info.Value; } else if (Keywords.Equals(info.LocalName, this.atoms.Space)) { scope.Space = TranslateXmlSpace(info.Value); } } } } private void FixupElement() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { this.mainNode.Prefix = this.atoms.Empty; } if (Keywords.Equals(this.mainNode.Prefix, this.atoms.Empty)) { if (Keywords.Equals(this.mainNode.NamespaceURI, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(this.mainNode.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(this.mainNode.NamespaceURI, nspace)) { if (thisScope) { // Prefix conflict this.mainNode.Prefix = GetPrefixForNamespace(this.mainNode.NamespaceURI); } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } OutputScope elementScope = this.scopeManager.CurrentElementScope; elementScope.Prefix = this.mainNode.Prefix; } private void FixupAttributes(int attributeCount) { for (int attr = 0; attr < attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.NamespaceURI, this.atoms.Empty)) { info.Prefix = this.atoms.Empty; } else { if (Keywords.Equals(info.Prefix, this.atoms.Empty)) { info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(info.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(info.NamespaceURI, nspace)) { if(thisScope) { // prefix conflict info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } } } private void AppendNamespaces() { for (int i = this.namespaceCount - 1; i >= 0; i --) { BuilderInfo attribute = (BuilderInfo) this.attributeList[NewAttribute()]; attribute.Initialize((BuilderInfo)this.namespaceList[i]); } } private void AnalyzeComment() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Comment); Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newComment = null; string comment = this.mainNode.Value; bool minus = false; int index = 0, begin = 0; for (; index < comment.Length; index ++) { switch (comment[index]) { case s_Minus: if (minus) { if (newComment == null) newComment = new StringBuilder(comment, begin, index, 2 * comment.Length); else newComment.Append(comment, begin, index - begin); newComment.Append(s_SpaceMinus); begin = index + 1; } minus = true; break; default: minus = false; break; } } if (newComment != null) { if (begin < comment.Length) newComment.Append(comment, begin, comment.Length - begin); if (minus) newComment.Append(s_Space); this.mainNode.Value = newComment.ToString(); } else if (minus) { this.mainNode.ValueAppend(s_Space, false); } } private void AnalyzeProcessingInstruction() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.ProcessingInstruction || this.mainNode.NodeType == XmlNodeType.XmlDeclaration); //Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newPI = null; string pi = this.mainNode.Value; bool question = false; int index = 0, begin = 0; for (; index < pi.Length; index ++) { switch (pi[index]) { case s_Question: question = true; break; case s_Greater: if (question) { if (newPI == null) { newPI = new StringBuilder(pi, begin, index, 2 * pi.Length); } else { newPI.Append(pi, begin, index - begin); } newPI.Append(s_SpaceGreater); begin = index + 1; } question = false; break; default: question = false; break; } } if (newPI != null) { if (begin < pi.Length) { newPI.Append(pi, begin, pi.Length - begin); } this.mainNode.Value = newPI.ToString(); } } private void FinalizeRecord() { switch (this.mainNode.NodeType) { case XmlNodeType.Element: // Save count since FixupElement can add attribute... int attributeCount = this.attributeCount; FixupElement(); FixupAttributes(attributeCount); AnalyzeSpaceLang(); AppendNamespaces(); break; case XmlNodeType.Comment: AnalyzeComment(); break; case XmlNodeType.ProcessingInstruction: AnalyzeProcessingInstruction(); break; } } private int NewNamespace() { if (this.namespaceCount >= this.namespaceList.Count) { Debug.Assert(this.namespaceCount == this.namespaceList.Count); this.namespaceList.Add(new BuilderInfo()); } return this.namespaceCount ++; } private void DeclareNamespace(string nspace, string prefix) { int index = NewNamespace(); Debug.Assert(this.namespaceList[index] != null && this.namespaceList[index] is BuilderInfo); BuilderInfo ns = (BuilderInfo) this.namespaceList[index]; if (prefix == this.atoms.Empty) { ns.Initialize(this.atoms.Empty, this.atoms.Xmlns, this.atoms.XmlnsNamespace); } else { ns.Initialize(this.atoms.Xmlns, prefix, this.atoms.XmlnsNamespace); } ns.Depth = this.recordDepth; ns.NodeType = XmlNodeType.Attribute; ns.Value = nspace; this.scopeManager.PushNamespace(prefix, nspace); } private string DeclareNewNamespace(string nspace) { string prefix = this.scopeManager.GeneratePrefix(PrefixFormat); DeclareNamespace(nspace, prefix); return prefix; } internal string GetPrefixForNamespace(string nspace) { string prefix = null; if (this.scopeManager.FindPrefix(nspace, out prefix)) { Debug.Assert(prefix != null && prefix.Length > 0); return prefix; } else { return DeclareNewNamespace(nspace); } } private static XmlSpace TranslateXmlSpace(string space) { if (Keywords.Compare(space, s_SpaceDefault)) { return XmlSpace.Default; } else if (Keywords.Compare(space, s_SpacePreserve)) { return XmlSpace.Preserve; } else { return XmlSpace.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.XsltOld { using Res = System.Xml.Utils.Res; using System; using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.XPath; using System.Collections; internal sealed class RecordBuilder { private int outputState; private RecordBuilder next; RecordOutput output; // Atomization: private XmlNameTable nameTable; private OutKeywords atoms; // Namespace manager for output private OutputScopeManager scopeManager; // Main node + Fields Collection private BuilderInfo mainNode = new BuilderInfo(); private ArrayList attributeList = new ArrayList(); private int attributeCount; private ArrayList namespaceList = new ArrayList(); private int namespaceCount; private BuilderInfo dummy = new BuilderInfo(); // Current position in the list private BuilderInfo currentInfo; // Builder state private bool popScope; private int recordState; private int recordDepth; private const int NoRecord = 0; // No part of a new record was generated (old record was cleared out) private const int SomeRecord = 1; // Record was generated partially (can be eventually record) private const int HaveRecord = 2; // Record was fully generated private const char s_Minus = '-'; private const string s_Space = " "; private const string s_SpaceMinus = " -"; private const char s_Question = '?'; private const char s_Greater = '>'; private const string s_SpaceGreater = " >"; private const string PrefixFormat = "xp_{0}"; private const string s_SpaceDefault = "default"; private const string s_SpacePreserve = "preserve"; internal RecordBuilder(RecordOutput output, XmlNameTable nameTable) { Debug.Assert(output != null); this.output = output; this.nameTable = nameTable != null ? nameTable : new NameTable(); this.atoms = new OutKeywords(this.nameTable); this.scopeManager = new OutputScopeManager(this.nameTable, this.atoms); } // // Internal properties // internal int OutputState { get { return this.outputState; } set { this.outputState = value; } } internal RecordBuilder Next { get { return this.next; } set { this.next = value; } } internal RecordOutput Output { get { return this.output; } } internal BuilderInfo MainNode { get { return this.mainNode; } } internal ArrayList AttributeList { get { return this.attributeList; } } internal int AttributeCount { get { return this.attributeCount; } } internal OutputScopeManager Manager { get { return this.scopeManager; } } private void ValueAppend(string s, bool disableOutputEscaping) { this.currentInfo.ValueAppend(s, disableOutputEscaping); } private bool CanOutput(int state) { Debug.Assert(this.recordState != HaveRecord); // If we have no record cached or the next event doesn't start new record, we are OK if (this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0) { return true; } else { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this) == Processor.OutputResult.Continue; } } internal Processor.OutputResult BeginEvent(int state, XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); prefix = (prefix != null) ? this.nameTable.Add(prefix) : this.atoms.Empty; name = (name != null) ? this.nameTable.Add(name) : this.atoms.Empty; nspace = (nspace != null) ? this.nameTable.Add(nspace) : this.atoms.Empty; switch (nodeType) { case XPathNodeType.Element: this.mainNode.htmlProps = htmlProps as HtmlElementProps; this.mainNode.search = search; BeginElement(prefix, name, nspace, empty); break; case XPathNodeType.Attribute: BeginAttribute(prefix, name, nspace, htmlProps, search); break; case XPathNodeType.Namespace: BeginNamespace(name, nspace); break; case XPathNodeType.Text: break; case XPathNodeType.ProcessingInstruction: if (BeginProcessingInstruction(prefix, name, nspace) == false) { return Processor.OutputResult.Error; } break; case XPathNodeType.Comment: BeginComment(); break; case XPathNodeType.Root: break; case XPathNodeType.Whitespace: case XPathNodeType.SignificantWhitespace: case XPathNodeType.All: break; } return CheckRecordBegin(state); } internal Processor.OutputResult TextEvent(int state, string text, bool disableOutputEscaping) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } Debug.Assert(this.recordState == NoRecord || (state & StateMachine.BeginRecord) == 0); AdjustDepth(state); ResetRecord(state); PopElementScope(); if ((state & StateMachine.BeginRecord) != 0) { this.currentInfo.Depth = this.recordDepth; this.currentInfo.NodeType = XmlNodeType.Text; } ValueAppend(text, disableOutputEscaping); return CheckRecordBegin(state); } internal Processor.OutputResult EndEvent(int state, XPathNodeType nodeType) { if (! CanOutput(state)) { return Processor.OutputResult.Overflow; } AdjustDepth(state); PopElementScope(); this.popScope = (state & StateMachine.PopScope) != 0; if ((state & StateMachine.EmptyTag) != 0 && this.mainNode.IsEmptyTag == true) { return Processor.OutputResult.Continue; } ResetRecord(state); if ((state & StateMachine.BeginRecord) != 0) { if(nodeType == XPathNodeType.Element) { EndElement(); } } return CheckRecordEnd(state); } internal void Reset() { if (this.recordState == HaveRecord) { this.recordState = NoRecord; } } internal void TheEnd() { if (this.recordState == SomeRecord) { this.recordState = HaveRecord; FinalizeRecord(); this.output.RecordDone(this); } this.output.TheEnd(); } // // Utility implementation methods // private int FindAttribute(string name, string nspace, ref string prefix) { Debug.Assert(this.attributeCount <= this.attributeList.Count); for (int attrib = 0; attrib < this.attributeCount; attrib ++) { Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; if (Keywords.Equals(attribute.LocalName, name)) { if (Keywords.Equals(attribute.NamespaceURI, nspace)) { return attrib; } if (Keywords.Equals(attribute.Prefix, prefix)) { // prefix conflict. Should be renamed. prefix = string.Empty; } } } return -1; } private void BeginElement(string prefix, string name, string nspace, bool empty) { Debug.Assert(this.attributeCount == 0); this.currentInfo.NodeType = XmlNodeType.Element; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; this.currentInfo.IsEmptyTag = empty; this.scopeManager.PushScope(name, nspace, prefix); } private void EndElement() { Debug.Assert(this.attributeCount == 0); OutputScope elementScope = this.scopeManager.CurrentElementScope; this.currentInfo.NodeType = XmlNodeType.EndElement; this.currentInfo.Prefix = elementScope.Prefix; this.currentInfo.LocalName = elementScope.Name; this.currentInfo.NamespaceURI = elementScope.Namespace; this.currentInfo.Depth = this.recordDepth; } private int NewAttribute() { if (this.attributeCount >= this.attributeList.Count) { Debug.Assert(this.attributeCount == this.attributeList.Count); this.attributeList.Add(new BuilderInfo()); } return this.attributeCount ++; } private void BeginAttribute(string prefix, string name, string nspace, Object htmlAttrProps, bool search) { int attrib = FindAttribute(name, nspace, ref prefix); if (attrib == -1) { attrib = NewAttribute(); } Debug.Assert(this.attributeList[attrib] != null && this.attributeList[attrib] is BuilderInfo); BuilderInfo attribute = (BuilderInfo) this.attributeList[attrib]; attribute.Initialize(prefix, name, nspace); attribute.Depth = this.recordDepth; attribute.NodeType = XmlNodeType.Attribute; attribute.htmlAttrProps = htmlAttrProps as HtmlAttributeProps; attribute.search = search; this.currentInfo = attribute; } private void BeginNamespace(string name, string nspace) { bool thisScope = false; if (Keywords.Equals(name, this.atoms.Empty)) { if (Keywords.Equals(nspace, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { // http://www.w3.org/1999/11/REC-xslt-19991116-errata/ E25 // Should throw an error but ingnoring it in Everett. // Would be a breaking change } else { DeclareNamespace(nspace, name); } } else { string nspaceDeclared = this.scopeManager.ResolveNamespace(name, out thisScope); if (nspaceDeclared != null) { if (! Keywords.Equals(nspace, nspaceDeclared)) { if(!thisScope) { DeclareNamespace(nspace, name); } } } else { DeclareNamespace(nspace, name); } } this.currentInfo = dummy; currentInfo.NodeType = XmlNodeType.Attribute; } private bool BeginProcessingInstruction(string prefix, string name, string nspace) { this.currentInfo.NodeType = XmlNodeType.ProcessingInstruction; this.currentInfo.Prefix = prefix; this.currentInfo.LocalName = name; this.currentInfo.NamespaceURI = nspace; this.currentInfo.Depth = this.recordDepth; return true; } private void BeginComment() { this.currentInfo.NodeType = XmlNodeType.Comment; this.currentInfo.Depth = this.recordDepth; } private void AdjustDepth(int state) { switch (state & StateMachine.DepthMask) { case StateMachine.DepthUp: this.recordDepth ++; break; case StateMachine.DepthDown: this.recordDepth --; break; default: break; } } private void ResetRecord(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.BeginRecord) != 0) { this.attributeCount = 0; this.namespaceCount = 0; this.currentInfo = this.mainNode; this.currentInfo.Initialize(this.atoms.Empty, this.atoms.Empty, this.atoms.Empty); this.currentInfo.NodeType = XmlNodeType.None; this.currentInfo.IsEmptyTag = false; this.currentInfo.htmlProps = null; this.currentInfo.htmlAttrProps = null; } } private void PopElementScope() { if (this.popScope) { this.scopeManager.PopScope(); this.popScope = false; } } private Processor.OutputResult CheckRecordBegin(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { this.recordState = SomeRecord; return Processor.OutputResult.Continue; } } private Processor.OutputResult CheckRecordEnd(int state) { Debug.Assert(this.recordState == NoRecord || this.recordState == SomeRecord); if ((state & StateMachine.EndRecord) != 0) { this.recordState = HaveRecord; FinalizeRecord(); SetEmptyFlag(state); return this.output.RecordDone(this); } else { // For end event, if there is no end token, don't force token return Processor.OutputResult.Continue; } } private void SetEmptyFlag(int state) { Debug.Assert(this.mainNode != null); if ((state & StateMachine.BeginChild) != 0) { this.mainNode.IsEmptyTag = false; } } private void AnalyzeSpaceLang() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); for (int attr = 0; attr < this.attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.Prefix, this.atoms.Xml)) { OutputScope scope = this.scopeManager.CurrentElementScope; if (Keywords.Equals(info.LocalName, this.atoms.Lang)) { scope.Lang = info.Value; } else if (Keywords.Equals(info.LocalName, this.atoms.Space)) { scope.Space = TranslateXmlSpace(info.Value); } } } } private void FixupElement() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Element); if (Keywords.Equals(this.mainNode.NamespaceURI, this.atoms.Empty)) { this.mainNode.Prefix = this.atoms.Empty; } if (Keywords.Equals(this.mainNode.Prefix, this.atoms.Empty)) { if (Keywords.Equals(this.mainNode.NamespaceURI, this.scopeManager.DefaultNamespace)) { // Main Node is OK } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(this.mainNode.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(this.mainNode.NamespaceURI, nspace)) { if (thisScope) { // Prefix conflict this.mainNode.Prefix = GetPrefixForNamespace(this.mainNode.NamespaceURI); } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } } else { DeclareNamespace(this.mainNode.NamespaceURI, this.mainNode.Prefix); } } OutputScope elementScope = this.scopeManager.CurrentElementScope; elementScope.Prefix = this.mainNode.Prefix; } private void FixupAttributes(int attributeCount) { for (int attr = 0; attr < attributeCount; attr ++) { Debug.Assert(this.attributeList[attr] is BuilderInfo); BuilderInfo info = (BuilderInfo) this.attributeList[attr]; if (Keywords.Equals(info.NamespaceURI, this.atoms.Empty)) { info.Prefix = this.atoms.Empty; } else { if (Keywords.Equals(info.Prefix, this.atoms.Empty)) { info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { bool thisScope = false; string nspace = this.scopeManager.ResolveNamespace(info.Prefix, out thisScope); if (nspace != null) { if (! Keywords.Equals(info.NamespaceURI, nspace)) { if(thisScope) { // prefix conflict info.Prefix = GetPrefixForNamespace(info.NamespaceURI); } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } else { DeclareNamespace(info.NamespaceURI, info.Prefix); } } } } } private void AppendNamespaces() { for (int i = this.namespaceCount - 1; i >= 0; i --) { BuilderInfo attribute = (BuilderInfo) this.attributeList[NewAttribute()]; attribute.Initialize((BuilderInfo)this.namespaceList[i]); } } private void AnalyzeComment() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.Comment); Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newComment = null; string comment = this.mainNode.Value; bool minus = false; int index = 0, begin = 0; for (; index < comment.Length; index ++) { switch (comment[index]) { case s_Minus: if (minus) { if (newComment == null) newComment = new StringBuilder(comment, begin, index, 2 * comment.Length); else newComment.Append(comment, begin, index - begin); newComment.Append(s_SpaceMinus); begin = index + 1; } minus = true; break; default: minus = false; break; } } if (newComment != null) { if (begin < comment.Length) newComment.Append(comment, begin, comment.Length - begin); if (minus) newComment.Append(s_Space); this.mainNode.Value = newComment.ToString(); } else if (minus) { this.mainNode.ValueAppend(s_Space, false); } } private void AnalyzeProcessingInstruction() { Debug.Assert(this.mainNode.NodeType == XmlNodeType.ProcessingInstruction || this.mainNode.NodeType == XmlNodeType.XmlDeclaration); //Debug.Assert((object) this.currentInfo == (object) this.mainNode); StringBuilder newPI = null; string pi = this.mainNode.Value; bool question = false; int index = 0, begin = 0; for (; index < pi.Length; index ++) { switch (pi[index]) { case s_Question: question = true; break; case s_Greater: if (question) { if (newPI == null) { newPI = new StringBuilder(pi, begin, index, 2 * pi.Length); } else { newPI.Append(pi, begin, index - begin); } newPI.Append(s_SpaceGreater); begin = index + 1; } question = false; break; default: question = false; break; } } if (newPI != null) { if (begin < pi.Length) { newPI.Append(pi, begin, pi.Length - begin); } this.mainNode.Value = newPI.ToString(); } } private void FinalizeRecord() { switch (this.mainNode.NodeType) { case XmlNodeType.Element: // Save count since FixupElement can add attribute... int attributeCount = this.attributeCount; FixupElement(); FixupAttributes(attributeCount); AnalyzeSpaceLang(); AppendNamespaces(); break; case XmlNodeType.Comment: AnalyzeComment(); break; case XmlNodeType.ProcessingInstruction: AnalyzeProcessingInstruction(); break; } } private int NewNamespace() { if (this.namespaceCount >= this.namespaceList.Count) { Debug.Assert(this.namespaceCount == this.namespaceList.Count); this.namespaceList.Add(new BuilderInfo()); } return this.namespaceCount ++; } private void DeclareNamespace(string nspace, string prefix) { int index = NewNamespace(); Debug.Assert(this.namespaceList[index] != null && this.namespaceList[index] is BuilderInfo); BuilderInfo ns = (BuilderInfo) this.namespaceList[index]; if (prefix == this.atoms.Empty) { ns.Initialize(this.atoms.Empty, this.atoms.Xmlns, this.atoms.XmlnsNamespace); } else { ns.Initialize(this.atoms.Xmlns, prefix, this.atoms.XmlnsNamespace); } ns.Depth = this.recordDepth; ns.NodeType = XmlNodeType.Attribute; ns.Value = nspace; this.scopeManager.PushNamespace(prefix, nspace); } private string DeclareNewNamespace(string nspace) { string prefix = this.scopeManager.GeneratePrefix(PrefixFormat); DeclareNamespace(nspace, prefix); return prefix; } internal string GetPrefixForNamespace(string nspace) { string prefix = null; if (this.scopeManager.FindPrefix(nspace, out prefix)) { Debug.Assert(prefix != null && prefix.Length > 0); return prefix; } else { return DeclareNewNamespace(nspace); } } private static XmlSpace TranslateXmlSpace(string space) { if (Keywords.Compare(space, s_SpaceDefault)) { return XmlSpace.Default; } else if (Keywords.Compare(space, s_SpacePreserve)) { return XmlSpace.Preserve; } else { return XmlSpace.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Win32NamedPipes.cs
- cookie.cs
- TypeInfo.cs
- TemplatedMailWebEventProvider.cs
- SystemDiagnosticsSection.cs
- BoundField.cs
- DataGridViewRowEventArgs.cs
- EdmScalarPropertyAttribute.cs
- ConfigurationSectionGroup.cs
- CombinedGeometry.cs
- DtrList.cs
- HtmlContainerControl.cs
- ConfigurationManagerInternal.cs
- XmlObjectSerializer.cs
- ProxySimple.cs
- SiteMapHierarchicalDataSourceView.cs
- HexParser.cs
- TextTabProperties.cs
- TypeBuilderInstantiation.cs
- RawMouseInputReport.cs
- Pair.cs
- Utility.cs
- EmbossBitmapEffect.cs
- ObjectPropertyMapping.cs
- SingleAnimationUsingKeyFrames.cs
- XmlNodeReader.cs
- IgnoreFileBuildProvider.cs
- StrokeNodeEnumerator.cs
- DataContract.cs
- DescriptionCreator.cs
- ApplicationSettingsBase.cs
- WebPartConnectionsEventArgs.cs
- Misc.cs
- DataContractJsonSerializer.cs
- ExpressionCopier.cs
- GridView.cs
- RelationalExpressions.cs
- LinqDataSourceInsertEventArgs.cs
- WindowsButton.cs
- CloudCollection.cs
- RuntimeConfigLKG.cs
- SiteIdentityPermission.cs
- PartialToken.cs
- AccessText.cs
- TextTreeNode.cs
- ProviderIncompatibleException.cs
- FixedTextSelectionProcessor.cs
- VariantWrapper.cs
- HttpMethodAttribute.cs
- FileSystemEnumerable.cs
- TypePresenter.xaml.cs
- CodeDomLocalizationProvider.cs
- ChannelToken.cs
- StateMachine.cs
- Matrix3D.cs
- SecurityBindingElementImporter.cs
- PermissionSet.cs
- InvokeProviderWrapper.cs
- ClientRolePrincipal.cs
- GiveFeedbackEvent.cs
- DocumentPageTextView.cs
- CompilerErrorCollection.cs
- SingleAnimation.cs
- ReadOnlyDataSource.cs
- HandlerBase.cs
- XPathAncestorIterator.cs
- CacheOutputQuery.cs
- RequestCachePolicyConverter.cs
- InputLanguageManager.cs
- ChannelReliableSession.cs
- FileEnumerator.cs
- TextDecorationUnitValidation.cs
- BlockExpression.cs
- DES.cs
- DecimalAnimation.cs
- PopupRootAutomationPeer.cs
- RootAction.cs
- RuntimeConfig.cs
- XmlSchemaAnyAttribute.cs
- TextElementCollection.cs
- PolicyStatement.cs
- TypeLibConverter.cs
- TouchPoint.cs
- FormsAuthenticationCredentials.cs
- AuthorizationRule.cs
- SourceItem.cs
- GridViewRowPresenter.cs
- DesignerTransaction.cs
- MatrixUtil.cs
- UserControlCodeDomTreeGenerator.cs
- TemplateEditingFrame.cs
- KeyValueSerializer.cs
- TabControlEvent.cs
- ForEachAction.cs
- ToolBarButton.cs
- ADMembershipUser.cs
- WmlControlAdapter.cs
- SrgsElementFactoryCompiler.cs
- FieldMetadata.cs
- CriticalExceptions.cs