2016-05-25 28 views
3

这是我第一次使用Html Agility Pack并直接面临问题。使用Html Agility Pack获取整个表单元素作为字符串

正如我的标题所示,我想将整个元素作为字符串包括内部元素。下面

因此,例如,是我的HTML,我用ID搜索表单元素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> 

我通常不喜欢问这样的汤匙喂养问题,但我一直在尝试和寻找,但无法得到答案。

请帮忙!

在此先感谢!

回答

4

好像你正在寻找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; 

UPDATE

似乎有一个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; 
+0

OuterHtml,他的例子 - 也不会回到他想要什么。 – Veverke

+0

@Veverke,根据规格,它应该。除非我错过了一些东西,否则它会成为一个错误。 –

+0

@Veverke请参阅[dotNetFiddle上的示例](https://dotnetfiddle.net/YCu5RJ)(XmlDocument,因为dotNetFiddle没有HtmlAgilityPack,否则它是一样的) –

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包不)

使用AngleSharp - 工作

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

输出(使用AngleSharp):

enter image description here

+0

'OuterHtml',而不是'InnerHtml' –

+0

检查出来,外层不会返回他想要的。 – Veverke

+0

这个问题提出了一些有趣的结果......一个是'ScrapySharp'的'CssSelect'不会接受css selector'*> form'来获得父节点是'form'的任何节点 - 而'AngleSharp'的' QuerySelector'将接受 - 并返回正确的内部html。 (ScrapySharp的css选择器确实存在问题,这不是可靠的......) – Veverke

相关问题