HTML Agility Pack是否可以基于名称属性来定位元素?

问题描述 投票:0回答:1

使用Html Agility Pack,是否有可能通过查找其名称属性而不是其在节点列表中的索引位置来定位特定元素值?例如,如果更改表单元素的顺序,如何将name="description"的元素作为目标,并检查表单中是否还存在该元素?

HTML示例:

<form>
    <input type="hidden" name="title" value="example">
    <input type="hidden" name="body" value="example">
    <input type="hidden" name="description" value="example">
    <input type="hidden" name="category" value="example">
    <input type="hidden" name="date" value="example">
</form

C#通过索引号定位元素。之所以失败,是因为并非所有HTML文件都具有相同顺序的表单元素,并且有时缺少输入元素:

var doc = new HtmlDocument();
doc.Load(file);
var form = doc.DocumentNode.SelectSingleNode("//form");
var elements = form.SelectNodes("//input");

MyObject Obj = new MyObject();
Obj.Title = elements[0].Attributes["value"].Value;
Obj.Body = elements[1].Attributes["value"].Value;
Obj.Description = elements[2].Attributes["value"].Value;
Obj.Category = elements[3].Attributes["value"].Value;
Obj.Date = elements[4].Attributes["value"].Value;
c# html html-agility-pack
1个回答
0
投票

通过使用Html-Agility-Pack中的XPath,您几乎可以在html文档中搜索任何内容。

您正在使用的XPath查找整个forminputs的列表,但您没有在寻找特定的东西。

如果需要具有属性name且具有description值的特定元素,则可以使用以下xpath进行查找。

var doc = new HtmlDocument();
doc.Load(file);

var inputNode = doc.DocumentNode.SelectSingleNode("//input[@name='description']");

if (inputNode == null)
{
   Console.WriteLine("Empty Gift Box"); // nothing found.
}
else
{
   Console.WriteLine(inputNode.Attributes["value"].Value.ToString());
}
// Prints 'example'

// Or you can use a single line lookup and assignment.
// Note.. ?. means if the result was null / not found, set left side = null.
Obj.Title = doc.DocumentNode.SelectSingleNode("//input[@name='title']")?.Attributes["value"]?.Value.ToString();

它如何工作

//搜索整个文档/在标签之前(// form / input)之后立即查找标签。如果在表单和输入之间存在另一个标签,则将产生0个结果。.//搜索您正在调用SelectNodes的特定标签下的任何标签。如果外部有输入标签,则它们不会在grandChild下捕获。

var parentNode = doc.DocumentNode.SelectNodes("//form");
var grandChild = parentNode.SelectNodes(".//input"); // must be part of form.

如果要搜索输入的特定索引,属性或值,则可以使用关键字搜索,

// Get any first node that has both name and value
var specificNode = doc.DocumentNode.SelectSingleNode("//input[@name and @value]");  

// Get first node that has specific name and value
var specificNode2 = doc.DocumentNode.SelectSingleNode("//input[@name='description' and @value='example']");

// Get 3rd input element
var thirdInput = doc.DocumentNode.SelectSingleNode("//input[3]");

[在文档中还有许多其他搜索方式,但这应该可以使您脱颖而出。确保确保已阅读HAP Documentation.,并且在Html-Agility-Pack tag]下的StackOverflow上已经有很多答案

© www.soinside.com 2019 - 2024. All rights reserved.