internal HtmlElement(HtmlTagInfo tagInfo) { Name = tagInfo.TagName; if (!string.IsNullOrEmpty(tagInfo.Text)) { Contents.Add(tagInfo.Text); } }
private HtmlTagInfo ParseTag() { var getDelimiterByLength = new Func<IEnumerable<HtmlDelimiter>, int, HtmlDelimiter>((delims, length) => { return delims.Single(d => d.Length == length); }); // read left tag delimiter var delimiterLength = 0; var currentDelimiters = HtmlGrammar.Delimiters.All; do { var delimiters = HtmlGrammar.Delimiters.Find(currentDelimiters, Html.Current, ++delimiterLength).ToList(); if (delimiters.Count == 0) { --delimiterLength; break; } currentDelimiters = delimiters; } while (Html.MoveNext()); var leftDelimiter = getDelimiterByLength(currentDelimiters, delimiterLength); if (!Html.Current.IsTagNameChar()) { throw new Exception("Invalid html!"); } // read tag name var tagName = new StringBuilder(); do { tagName.Append(Html.Current); } while (Html.MoveNext() && Html.Current.IsTagNameChar()); // read attributes var attributes = new StringBuilder(); if (Html.Current.IsSpace()) { while (Html.MoveNext() && !Html.Current.IsClosingAngleBracket()) { attributes.Append(Html.Current); } } // read right tag delimiter delimiterLength = 0; currentDelimiters = leftDelimiter.NextDelimiters.ToList(); do { var delimiters = HtmlGrammar.Delimiters.Find(currentDelimiters, Html.Current, ++delimiterLength).ToList(); if (delimiters.Count == 0) { --delimiterLength; break; } currentDelimiters = delimiters; } while (Html.MoveNext()); var rightDelimiter = getDelimiterByLength(currentDelimiters, delimiterLength); if (!leftDelimiter.IsNext(rightDelimiter)) { throw new Exception("Invalid html"); } var tagInfo = new HtmlTagInfo { TagName = tagName.ToString(), TagType = HtmlGrammar.IdentifyTagType(leftDelimiter, rightDelimiter), // remove / on invalid self closing tags Attributes = attributes.ToString().TrimEnd('/') }; return tagInfo; }