public void CopyAttributes(Node n) { for (int i = 0, len = n.attributes.Count; i < len; i++) { Attribute a = (Attribute)n.attributes[i]; Attribute na = this.AddAttribute(a.Name, a.Value, a.QuoteChar, false); na.DtdType = a.DtdType; } }
void Init() { this.state = State.Initial; this.stack = new HWStack(10); this.node = Push(null, XmlNodeType.Document, null); this.node.IsEmpty = false; this.sb = new StringBuilder(); this.name = new StringBuilder(); this.poptodepth = 0; this.current = null; this.partial = '\0'; this.endTag = null; this.a = null; this.apos = 0; this.newnode = null; this.rootCount = 0; this.foundRoot = false; }
public override bool Read() { if (current == null) { OpenInput(); } State start = this.state; if (node.Simulated) { node.Simulated = false; this.node = Top(); this.state = this.node.CurrentState; return true; } bool foundnode = false; while (!foundnode) { switch (this.state) { case State.Initial: this.state = State.Markup; this.current.ReadChar(); goto case State.Markup; case State.Eof: if (this.current.Parent != null) { this.current.Close(); this.current = this.current.Parent; } else { return false; } break; case State.EndTag: if (this.endTag == (object)this.node.Name) { Pop(); // we're done! this.state = State.Markup; goto case State.Markup; } Pop(); foundnode = true; break; case State.Markup: if (this.node.IsEmpty) { Pop(); } Node n = this.node; foundnode = ParseMarkup(); break; case State.PartialTag: Pop(); this.state = State.Markup; foundnode = ParseTag(this.partial); break; case State.PseudoStartTag: foundnode = ParseStartTag('<'); break; case State.AutoClose: Pop(); if (this.stack.Count <= this.poptodepth) { this.state = State.Markup; if (this.newnode != null) { Push(this.newnode); this.newnode = null; this.state = State.Markup; } else if (this.node.NodeType == XmlNodeType.Document) { this.state = State.Eof; goto case State.Eof; } } foundnode = true; break; case State.CData: foundnode = ParseCData(); break; case State.Attr: goto case State.AttrValue; case State.AttrValue: this.state = State.Markup; goto case State.Markup; case State.Text: Pop(); goto case State.Markup; case State.PartialText: if (ParseText(this.current.Lastchar, false)) { this.node.NodeType = XmlNodeType.Whitespace; } foundnode = true; break; } if (foundnode && this.node.NodeType == XmlNodeType.Whitespace && this.whitespaceHandling == WhitespaceHandling.None) { foundnode = false; } if (!foundnode && this.state == State.Eof && this.stack.Count > 1) { this.poptodepth = 1; state = State.AutoClose; this.node = Top(); return true; } } if (!foundRoot && (this.NodeType == XmlNodeType.Element || this.NodeType == XmlNodeType.Text || this.NodeType == XmlNodeType.CDATA)) { foundRoot = true; if (this.IsHtml && (this.NodeType != XmlNodeType.Element || string.Compare(this.LocalName, "html", true, System.Globalization.CultureInfo.InvariantCulture) != 0)) { this.node.CurrentState = this.state; Node root = Push("html", XmlNodeType.Element, null); SwapTopNodes(); this.node = root; root.Simulated = true; root.IsEmpty = false; this.state = State.Markup; } return true; } return true; }
void ValidateContent(Node node) { if (this.dtd != null) { string name = this.nametable.Add(node.Name.ToUpper()); int i = 0; int top = this.stack.Count - 2; if (node.DtdType != null) { for (i = top; i > 0; i--) { Node n = (Node)this.stack[i]; if (n.IsEmpty) continue; ElementDecl f = n.DtdType; if (f != null) { if (f.Name == this.dtd.Name) break; if (f.CanContain(name, this.dtd)) { break; } else if (!f.EndTagOptional) { break; } } else { break; } } } if (i == 0) { } else if (i < top) { Node n = (Node)this.stack[top]; if (i == top - 1 && name == n.Name) { } else { string closing = ""; for (int k = top; k >= i + 1; k--) { if (closing != "") closing += ","; Node n2 = (Node)this.stack[k]; closing += "<" + n2.Name + ">"; } Log("Element '{0}' not allowed inside '{1}', closing {2}.", name, n.Name, closing); } this.state = State.AutoClose; this.newnode = node; Pop(); this.poptodepth = i + 1; } } }
void ValidateAttribute(Node node, Attribute a) { ElementDecl e = node.DtdType; if (e != null) { AttDef ad = e.FindAttribute(a.Name); if (ad != null) { a.DtdType = ad; } } }
void Validate(Node node) { if (this.dtd != null) { ElementDecl e = this.dtd.FindElement(node.Name); if (e != null) { node.DtdType = e; if (e.ContentModel.DeclaredContent == DeclaredContent.EMPTY) node.IsEmpty = true; } } }
Node Push(Node n) { Node n2 = Push(n.Name, n.NodeType, n.Value); n2.DtdType = n.DtdType; n2.IsEmpty = n.IsEmpty; n2.Space = n.Space; n2.XmlLang = n.XmlLang; n2.CurrentState = n.CurrentState; n2.CopyAttributes(n); this.node = n2; return n2; }
Node Push(string name, XmlNodeType nt, string value) { Node result = (Node)this.stack.Push(); if (result == null) { result = new Node(); this.stack[this.stack.Count - 1] = result; } result.Reset(name, nt, value); this.node = result; return result; }
void Pop() { if (this.stack.Count > 1) { this.node = (Node)this.stack.Pop(); } }
bool ParseEndTag() { this.state = State.EndTag; this.current.ReadChar(); string name = this.ScanName(SgmlReader.tagterm); char ch = this.current.SkipWhitespace(); if (ch != '>') { Log("Expected empty start tag '/>' sequence instead of '{0}'", ch); this.current.ScanToEnd(null, "Recovering", ">"); } this.current.ReadChar(); this.endTag = name; bool caseInsensitive = (this.folding == CaseFolding.None); this.node = (Node)this.stack[this.stack.Count - 1]; for (int i = this.stack.Count - 1; i > 0; i--) { Node n = (Node)this.stack[i]; if (caseInsensitive && string.Compare(n.Name, name, true) == 0) { this.endTag = n.Name; return true; } else if ((object)n.Name == (object)name) { return true; } } Log("No matching start tag for '</{0}>'", name); this.state = State.Markup; return false; }