使用Html Agility Pack将整个表单元素作为字符串

时间:2016-05-25 13:22:30

标签: c# html-agility-pack

这是我第一次使用Html Agility Pack并立即面对问题。

正如我的标题所示,我希望将整个元素作为包含内部元素的字符串。

例如,下面是我的html,我正在搜索标识为aspnetForm的表单元素

<html>  
<head>  
</head>  
<body>  
  <form name="aspnetForm" id="aspnetForm">
    <div id="div1">  
        <a href="div1-a1">Link 1 inside div1</a>  
        <a href="div1-a2">Link 2 inside div1</a>  
    </div>  
    <a href="a3">Link 3 outside all divs</a>      
    <div id="div2">  
        <a href="div2-a1">Link 1 inside div2</a>  
        <a href="div2-a2">Link 2 inside div2</a>  
    </div> 
  </form> 
</body>  
</html>

我希望以下是输出(字符串中)

  <form name="aspnetForm" id="aspnetForm">
    <div id="div1">  
        <a href="div1-a1">Link 1 inside div1</a>  
        <a href="div1-a2">Link 2 inside div1</a>  
    </div>  
    <a href="a3">Link 3 outside all divs</a>      
    <div id="div2">  
        <a href="div2-a1">Link 1 inside div2</a>  
        <a href="div2-a2">Link 2 inside div2</a>  
    </div> 
  </form> 

我通常不喜欢问这样的勺子喂养问题,但我一直在尝试和搜索,但无法得到答案。

请帮忙!

提前致谢!

2 个答案:

答案 0 :(得分:5)

好像你正在寻找HtmlNode.OuterHtml

//
// Summary:
//     Gets or Sets the object and its content in HTML.
public virtual string OuterHtml { get; }

因此,您只需选择表单节点并获取其OuterHtml属性:

HtmlDocument doc = ... // load your HTML
HtmlNode formNode = doc.DocumentNode.SelectSingleNode("//form[@id='aspnetForm']");
string entireElementAsString = formNode.OuterHtml;

<强>更新

似乎有一个very old bug,其中包含HAP如何处理form标记。或者也许是it's a feature

无论如何,这是一个解决方法:

HtmlNode.ElementsFlags.Remove("form");

所以这应该有效:

HtmlNode.ElementsFlags.Remove("form");
HtmlDocument doc = ... // load your HTML
HtmlNode formNode = doc.DocumentNode.SelectSingleNode("//form[@id='aspnetForm']");
string entireElementAsString = formNode.OuterHtml;

答案 1 :(得分:1)

确实很好的问题,奇怪的是以下所有内容都失败了!

使用HtmlAgilityPack - 还没有能够提出解决方案!

(注意我也使用nuget库ScraySharp来获取Css选择器扩展(ScrapySharp.Extensions)

 string html = @"<html>
        <head>
        </head>
        <body>
          <form name='aspnetForm' id='aspnetForm'>
            <div id='div1'>
                <a href='div1-a1'>Link 1 inside div1</a>
                <a href='div1-a2'>Link 2 inside div1</a>
            </div>
            <a href='a3'>Link 3 outside all divs</a>
            <div id='div2'>
                <a href='div2-a1'>Link 1 inside div2</a>
                <a href='div2-a2'>Link 2 inside div2</a>
            </div>
          </form>
        </body>
        </html>";

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);

    string result = string.Empty;

    var formElement = doc.DocumentNode.CssSelect("form").FirstOrDefault();
    var formChildren = formElement.Descendants();

    StringBuilder sb = new StringBuilder();

    if (formChildren != null)
    {
        foreach (var child in formChildren)
        {
            sb.AppendLine(child.InnerHtml);
        }
    }

        //formElement.InnerHtml also returns empty !
        Console.WriteLine(sb.ToString());

然而,你可以通过AngleSharp轻松实现这一目标(角度锐利现在似乎是值得推荐的选择,因为它仍然保持/开发,而HtmlAgility Pack则没有。)

使用AngleSharp - 工作

 HtmlParser parser = new HtmlParser();
 var parsedDoc = parser.Parse(html);
 Console.WriteLine(parsedDoc.QuerySelector("form").InnerHtml);

输出(使用AngleSharp):

enter image description here