/// <summary>
        /// 指定したノードのフォーマット済みHtmlを返す
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public virtual string Format(HtmlElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            StringBuilder sb     = new StringBuilder();
            bool          format = false;

            // 開始タグ
            sb.Append("<").Append(element.Name);

            // 属性を付加
            foreach (HtmlAttribute attr in element.Attributes)
            {
                sb.Append(" ").Append(attr.Html);
            }

            if (element.Nodes.Count > 0)
            {
                sb.Append(">");

                indent++;

                // 子ノードのHtmlを生成
                foreach (HtmlNode child in element.Nodes)
                {
                    if (child is HtmlText)
                    {
                        HtmlText text = (HtmlText)child;
                        sb.Append(text.Content);

                        format = false;
                    }
                    else
                    {
                        HtmlElement childElem = (HtmlElement)child;

                        if (childElem.IsTerminated)
                        {
                            format = true;
                        }

                        if (format)
                        {
                            sb.Append(newline);
                            InsertSpace(sb, indent);
                        }

                        string html = Format(childElem);
                        sb.Append(html);

                        format = true;
                    }
                }

                --indent;

                if (format)
                {
                    sb.Append(newline);
                    InsertSpace(sb, indent);
                }

                sb.Append("</").Append(element.Name).Append(">");
            }
            else
            {
                if (element.IsEmptyElementTag)
                {
                    sb.Append("/>");
                }
                else if (element.IsTerminated)
                {
                    sb.Append("></").Append(element.Name).Append(">");
                }
                else
                {
                    sb.Append(">");
                }
            }

            return(sb.ToString());
        }
示例#2
0
        /// <summary>
        /// Htmlを解析してノードコレクションを生成
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public HtmlNodeCollection Parse(string html)
        {
            if (html == null)
            {
                throw new ArgumentNullException("html");
            }

            // 改行文字などを削除
            html = RemoveWhiteSpace(html);

            HtmlNodeCollection root = new HtmlNodeCollection(null);
            int index = 0;

            while (index < html.Length)
            {
                // コメントは無視する
                if (is_match(html, index, "<!--"))
                {
                    index += 4;

                    // コメントが終わるまでindexを進める
                    while (index < html.Length)
                    {
                        if (is_match(html, index, "-->"))
                        {
                            index += 3;
                            break;
                        }
                        index++;
                    }
                }
                // 閉じるタグの場合
                else if (is_match(html, index, "</"))
                {
                    index += 2;

                    // 空白読み飛ばし
                    SkipWhiteSpace(html, ref index);

                    // タグ名を取得
                    Match m = rexTagName.Match(html, index);
                    if (m.Success)
                    {
                        // 同じ名前の開始タグを取得
                        int nodeidx = BackFindOpenElement(root, m.Value);
                        if (nodeidx != -1)
                        {
                            NodesDown(root, nodeidx + 1, (HtmlElement)root[nodeidx]);
                        }
                        else
                        {
                            // throw new HtmlException();
                        }
                        index += m.Length;
                    }

                    // 終了タグが来るまでスキップ
                    SkipChars(html, ref index, "<>".ToCharArray());

                    if (is_match(html, index, ">"))
                    {
                        index++;
                    }
                }
                // 開始タグの場合
                else if (is_match(html, index, "<"))
                {
                    index += 1;

                    // 空白読み飛ばし
                    SkipWhiteSpace(html, ref index);

                    // タグ名を取得
                    Match m = rexTagName.Match(html, index);
                    if (m.Success)
                    {
                        HtmlElement e = new HtmlElement(m.Value.ToLower());
                        root.Add(e);

                        index = m.Index + m.Length;

                        // 空白読み飛ばし
                        SkipWhiteSpace(html, ref index);

                        // 属性の読み込み
                        if (not_match(html, index, "/>") &&
                            not_match(html, index, ">"))
                        {
                            ParseAttributes(html, ref index, e.Attributes);
                        }

                        // 1つで完結するタグの処理
                        if (is_match(html, index, "/>"))
                        {
                            e.IsEmptyElementTag = true;
                            index += 2;
                        }
                        // 終了タグの場合
                        else if (is_match(html, index, ">"))
                        {
                            index++;
                        }
                    }
                }
                // テキスト処理
                else
                {
                    // 開始タグを検索し、そこまでをテキストとする
                    int      next = html.IndexOf("<", index);
                    HtmlText text;

                    if (next == -1)
                    {
                        text  = new HtmlText(html.Substring(index));
                        index = html.Length;
                    }
                    else
                    {
                        text  = new HtmlText(html.Substring(index, next - index));
                        index = next;
                    }

                    root.Add(text);
                }
            }

            return(root);
        }