/// <summary> /// Start a depth-first traverse of the root and all of its descendants. /// </summary> /// <param name="root">The root node point to traverse.</param> public void Traverse(Node root) { Node node = root; int depth = 0; while (node != null) { _visitor.Head(node, depth); if (node.ChildNodes.Count > 0) { node = node.ChildNodes[0]; depth++; } else { while (node.NextSibling == null && depth > 0) { _visitor.Tail(node, depth); node = node.ParentNode; depth--; } _visitor.Tail(node, depth); if (node == root) { break; } node = node.NextSibling; } } }
public void Head(Node node, int depth) { if (node is Element) { Element el = (Element)node; if (eval.Matches(root, el)) { elements.Add(el); } } }
private void InsertNode(Node node) { CurrentElement.AppendChild(node); }
public void Tail(Node node, int depth) { if (!node.NodeName.Equals("#text")) // saves a void hit. { node.OuterHtmlTail(_accum, depth, _output); } }
public void Head(Node node, int depth) { node.OuterHtmlHead(_accum, depth, _output); }
protected Node DoClone(Node parent) { Node clone; try { // Originally: (Node)super.clone(); // Base class of Node is System.Object, therefore the following is needed: clone = (Node)this.MemberwiseClone(); } catch (Exception) { throw; } // Note: Original Java code accesses actual members, not accessors. clone._parentNode = parent; // can be null, to create an orphan split clone._siblingIndex = parent == null ? 0 : SiblingIndex; clone._attributes = Attributes != null ? (Attributes)Attributes.Clone() : null; clone._baseUri = _baseUri; clone._childNodes = new List<Node>(_childNodes.Count); // We have to use for, instead of foreach, since .NET does not allow addition of items inside foreach. for (int i = 0; i < _childNodes.Count; i++) { Node child = _childNodes[i]; clone._childNodes.Add(child.DoClone(clone)); // clone() creates orphans, doClone() keeps parent } return clone; }
private void ReParentChild(Node child) { if (child.ParentNode != null) { child.ParentNode.RemoveChild(child); } child.ParentNode = this; }
public void RemoveChild(Node output) { if (output._parentNode != this) { throw new ArgumentException("Output's parent node must be equal to this object."); } int index = output.SiblingIndex; _childNodes.RemoveAt(index); ReIndexChildren(); output._parentNode = null; }
public void Tail(Node node, int depth) { // void }
/// <summary> /// Replace this node in the DOM with the supplied node. /// </summary> /// <param name="input">in the node that will will replace the existing node.</param> public void ReplaceWith(Node input) { if (input == null) { throw new ArgumentNullException("input"); } if (ParentNode == null) { throw new InvalidOperationException("Parent node is null."); } ParentNode.ReplaceChild(this, input); }
/// <summary> /// Insert the specified node into the DOM after this node (i.e. as a following sibling). /// </summary> /// <param name="node">node to add after this node</param> /// <returns>this node, for chaining</returns> /// <see cref="Before(Node)"/> public virtual Node After(Node node) { if (node == null) { throw new ArgumentNullException("node"); } if (ParentNode == null) { throw new InvalidOperationException("ParentNode is null."); } _parentNode.AddChildren(SiblingIndex + 1, node); return this; }
// fast method to get first by tag name, used for html, head, body finders private Element FindFirstElementByTagName(string tag, Node node) { if (node.NodeName.Equals(tag)) { return (Element)node; } else { foreach (Node child in node.ChildNodes) { Element found = FindFirstElementByTagName(tag, child); if (found != null) { return found; } } } return null; }
public void InsertInFosterParent(Node input) { Element fosterParent = null; Element lastTable = GetFromStack("table"); bool isLastTableParent = false; if (lastTable != null) { if (lastTable.Parent != null) { fosterParent = lastTable.Parent; isLastTableParent = true; } else { fosterParent = AboveOnStack(lastTable); } } else { // no table == frag fosterParent = _stack.First.Value; } if (isLastTableParent) { if (lastTable == null) { throw new InvalidOperationException("lastTable is null."); } lastTable.Before(input); } else { fosterParent.AppendChild(input); } }
private void InsertNode(Node node) { // if the stack hasn't been set up yet, elements (doctype, comments) go into the doc if (_stack.Count == 0) { _doc.AppendChild(node); } else if (IsFosterInserts) { InsertInFosterParent(node); } else { CurrentElement.AppendChild(node); } }
public void Head(Node node, int depth) { accum.Append("<" + node.NodeName + ">"); }
public void Tail(Node node, int depth) { accum.Append("</" + node.NodeName + ">"); }
public void ReplaceChild(Node output, Node input) { if (output._parentNode != this) { throw new ArgumentException("Output's parent node must be equal to this object."); } if (input == null) { throw new ArgumentNullException("input"); } if (input._parentNode != null) { input._parentNode.RemoveChild(input); } int index = output.SiblingIndex; _childNodes[index] = input; input._parentNode = this; input.SiblingIndex = index; output._parentNode = null; }