null参照エラーを取得せずにHtmlAgilityPackでフォーム内のすべての入力要素を取得する方法


質問

HTMLの例:

 <html><body>
     <form id="form1">
       <input name="foo1" value="bar1" />
       <!-- Other elements -->
     </form>
     <form id="form2">
       <input name="foo2" value="bar2" />
       <!-- Other elements -->
     </form>   
 </body></html>

テストコード:

 <html><body>
     <form id="form1">
       <input name="foo1" value="bar1" />
       <!-- Other elements -->
     </form>
     <form id="form2">
       <input name="foo2" value="bar2" />
       <!-- Other elements -->
     </form>   
 </body></html>

doc.GetElementbyId("form2").SelectNodes(".//input")は私にnull参照を与えます。

私が間違っていたことは何ですか?ありがとう。

受け入れられた回答

次の操作を実行できます。

HtmlNode.ElementsFlags.Remove("form");

HtmlDocument doc = new HtmlDocument();

doc.Load(@"D:\test.html");

HtmlNode secondForm = doc.GetElementbyId("form2");

foreach (HtmlNode node in secondForm.Elements("input"))
{
    HtmlAttribute valueAttribute = node.Attributes["value"];

    if (valueAttribute != null)
    {
        Console.WriteLine(valueAttribute.Value);
    }
}

デフォルトでは、HTMLアジャイルパックはフォームを空のノードとして解析します。これは、他のHTML要素と重なり合うことが許可されているためです。最初の行( HtmlNode.ElementsFlags.Remove("form"); )は、この動作を無効にし、2番目のフォームの中で入力要素を取得できるようにします。

更新:フォーム要素の重なりの例:

HtmlNode.ElementsFlags.Remove("form");

HtmlDocument doc = new HtmlDocument();

doc.Load(@"D:\test.html");

HtmlNode secondForm = doc.GetElementbyId("form2");

foreach (HtmlNode node in secondForm.Elements("input"))
{
    HtmlAttribute valueAttribute = node.Attributes["value"];

    if (valueAttribute != null)
    {
        Console.WriteLine(valueAttribute.Value);
    }
}

要素はテーブル内で開始されますが、テーブル要素の外側で閉じられます。これはHTML仕様で許可されており、HTML Agility Packはそれに対処しなければなりません。


人気のある回答

ちょうどそれらを配列で得る:

HtmlNodeCollection resultCollection = doc.DocumentNode.SelectNodes("//*[@type='text']");




ライセンスを受けた: CC-BY-SA
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ