private void DumpNode(Node node) { StringBuilder wholeTag = new StringBuilder(node.GetText()); if (!(node is TextNode) && !(node is Comment)) { _builder.Append(GetIndentationString()); if (node is NodeContainer) { NodeContainer container = (NodeContainer)node; if (container is Element && container.Nodes.Count == 1 && container.Nodes[0] is TextNode) { // the container is an element and it only has text inside Element element = (Element)container; StringBuilder innerText = new StringBuilder(element.Nodes[0].GetText()); if (innerText.Length < MAX_TAG / 2) { _builder.Append(IndentOpeningTag(element, element.GetOpenTag())); _builder.Append(IndentText(innerText, false)); _builder.Append(element.GetCloseTag()); _builder.Append('\n'); return; } } if (!container.HasChildNodes) { // the element does not have have any children, its only the element tag wholeTag.Replace("\r", ""); wholeTag.Replace("\n", ""); _builder.Append(IndentOpeningTag(container, wholeTag.ToString())); _builder.Append('\n'); return; } if (container is Element) { // a normal element with any number of children. Element element = (Element)container; _builder.Append(IndentOpeningTag(element, element.GetOpenTag())); _builder.Append('\n'); _indentation++; DumpNodes(element.Nodes); _indentation--; _builder.Append(GetIndentationString()); _builder.Append(element.GetCloseTag()); _builder.Append('\n'); } else { // it's not an element and it does not have children. Just write it. _builder.Append(wholeTag); _builder.Append('\n'); } } else { // it is not a container object, just write it. _builder.Append(wholeTag); _builder.Append('\n'); return; } } else { // it is a textnode or a comment, write it with format. _builder.Append(IndentText(wholeTag, true)); _builder.Append("\r\n"); } }
private string IndentOpeningTag(NodeContainer container, string text) { if (!container.HasAttributes) { // if it doesn't have attributes, just return the open tag return(text); } int pos = text.IndexOf(container.Attributes[0].GetText()); StringBuilder wholeTag = new StringBuilder(); wholeTag.Append(text.Substring(0, pos)); //clean up the element string for (int i = wholeTag.Length - 1; i >= 0; i--) { if (wholeTag[i] != ' ' && wholeTag[i] != '\t' && wholeTag[i] != '\n' && wholeTag[i] != '\r') { if (i == wholeTag.Length - 1) { break; } wholeTag.Remove(i + 1, wholeTag.Length - i - 1); break; } } string newIndent = new string('\t', _indentation + 1); StringBuilder currentRow = new StringBuilder(MAX_TAG); bool isFirstRow = true; foreach (Attribute a in container.Attributes) { if (currentRow.Length >= MAX_TAG) { if (!isFirstRow) { wholeTag.Append('\n'); wholeTag.Append(newIndent); } isFirstRow = false; wholeTag.Append(currentRow); currentRow = new StringBuilder(MAX_TAG); } currentRow.Append(' '); currentRow.Append(a.GetText()); } //add the left over attributes if (currentRow.Length > 0) { if (!isFirstRow && currentRow.Length > 15) { wholeTag.Append('\n'); wholeTag.Append(newIndent); } wholeTag.Append(currentRow); } //add the closing element tag string lastAttributeText = container.Attributes[container.Attributes.Count - 1].GetText(); pos = text.LastIndexOf(lastAttributeText); string endTag = text.Substring(pos + lastAttributeText.Length).Replace(" ", "").Replace("\t", ""); if (endTag == "/>") { endTag = " " + endTag; } wholeTag.Append(endTag); return(wholeTag.ToString()); }
public TagDocument Parse(string text, int startIndex, bool justFirstTag) { _document = new TagDocument(text); NodeReader reader = new NodeReader(text, startIndex); NodeContainer current = _document; Node node = reader.ReadNext(); int nodeCount = 0; while (node != null) { if (node is ElementCloseTag) { if (string.Compare(node.Name, current.Name, _ignoreCase, CultureInfo.InvariantCulture) == 0) { ((Element)current).SetElementPosition(current.StartPosition, current.EndPosition, node.StartPosition, node.EndPosition); current = current.Parent; } else { // oops, we should fix the document here NodeContainer temp = current.Parent; ArrayList list = new ArrayList(); list.Add(current); while (temp != null) { if (string.Compare(node.Name, temp.Name, _ignoreCase, CultureInfo.InvariantCulture) == 0) { ((Element)temp).SetElementPosition(temp.StartPosition, temp.EndPosition, node.StartPosition, node.EndPosition); current = temp.Parent; for (int i = list.Count - 1; i >= 0; i--) { Element tempNode = (Element)list[i]; int index = temp.Nodes.IndexOf(tempNode) + 1; tempNode.SetIsInlineClosed(true); tempNode.SetIsClosed(false); for (int child = tempNode.Nodes.Count - 1; child >= 0; child--) { Node childNode = tempNode.Nodes[child]; tempNode.Nodes.Remove(childNode); childNode.SetParent(temp); temp.Nodes.Insert(index, childNode); } } break; } list.Add(temp); temp = temp.Parent; } if (temp == null) { // oops // this seems to be a never-opened tag, // must likely a wrongly nested like <b><i></b></i> // shall we try doing something??? nodeCount++; InvalidNode textNode = new InvalidNode(); textNode.SetPosition(node.StartPosition, node.EndPosition); textNode._globalIndex = nodeCount; current.Nodes.Add(textNode); _hasInvalidMarkup = true; } } } else { current.Nodes.Add(node); nodeCount++; node._globalIndex = nodeCount; if (node is Element) { Element element = (Element)node; if (!element.IsInlineClosed) { current = element; } } } if (justFirstTag) { // For wrongly nested documents I might end with more than one node, so // if the user said only one, then remove all of the rest if (_document.Nodes.Count > 1) { for (int i = _document.Nodes.Count; i > 1; i--) { _document.Nodes.RemoveAt(i); } } break; } node = reader.ReadNext(); } _document._nodeCount = nodeCount; return(_document); }
internal void SetParent(NodeContainer parent) { this._parent = parent; }
public AttributeCollection(NodeContainer parent) { this._parent = parent; }
internal NodeCollection(NodeContainer parent) { this._parent = parent; }