2016-05-25 17 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

それはそうですHAPがformタグをどのように扱うかについては、very old bugがあります。またはおそらく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、hmm仕様によると、それはすべきです。私が何かを見逃していなければ、そうでなければバグだろう。 –

+0

@Veverke dotNetFiddleの例(https://dotnetfiddle.net/YCu5RJ)(dotNetFiddleにはHtmlAgilityPackがないのでXmlDocument、それ以外は同じです) –

1

確かに良い質問、奇妙な十分な以下のすべてが失敗しました!

HtmlAgilityPackを使用する - まだ解決策を思い付くことができません!

(CSSセレクタの拡張子(ScrapySharp.Extensionsを得るために、私はnugetライブラリScraySharpとしても使用していることに注意してください)

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

「InnerHtml」ではなく「OuterHtml」 –

+0

それをチェックすると、アウターは自分が望むものを返さない。 – Veverke

+0

この質問は興味深い成果を上げています... ScrapSharpの 'CssSelect'は親が' form'であるノードを得るためにCSSセレクタ '*> form'を受け入れない - AngleSharpの' QuerySelector'は受け入れられ、正しいinner HTMLもここで返します。 (ScrapySharpは確かにCSSセレクタに問題がありますが、それはあまり信頼性がありません...) – Veverke

関連する問題