Html敏捷包按类别获取所有元素

我正在攻击html敏捷包,无法find正确的方式去做这件事。

例如:

var findclasses = _doc.DocumentNode.Descendants("div").Where(d => d.Attributes.Contains("class")); 

但是,显然你可以添加更多的类,然后divs,所以我尝试了这个..

 var allLinksWithDivAndClass = _doc.DocumentNode.SelectNodes("//*[@class=\"float\"]"); 

但是,这并不处理您添加多个类的情况下,“浮动”只是其中之一像这样..

 class="className float anotherclassName" 

有办法处理所有这一切吗? 我基本上想要select所有具有类=和包含浮动的节点。

**答案已经在我的博客文档中有详细的解释: Html Agility Pack按类别获取所有元素

只需在谓词中添加更多的子句:

 var findclasses = _doc.DocumentNode .Descendants( "div" ) .Where( d => d.Attributes.Contains("class") && d.Attributes["class"].Value.Contains("float") ); 

我可能会build议创build一个扩展方法的HasClass和使用它像这样:

 IEnumerable<HtmlNode> hasFloatClass = _doc.DocumentNode .Descendants( "div" ) .Where( div => div.HasClass( "float" ) ); public static Boolean HasClass(this HtmlNode element, String className) { if( element == null ) throw new ArgumentNullException( nameof(element) ); if( String.IsNullOrWhitespace( className ) ) throw new ArgumentNullException( nameof(className) ); if( element.NodeType != HtmlNodeType.Element ) return false; HtmlAttribute classAttrib = element.Attributes["class"]; if( classAttrib == null ) return false; Boolean hasClass = CheapClassListContains( classAttrib.Value, className, StringComparison.Ordinal ); return hasClass; } /// <summary>Performs optionally-whitespace-padded string search without new string allocations.</summary> /// <remarks>A regex might also work, but constructing a new regex every time this method is called would be expensive.</remarks> private static Boolean CheapClassListContains(String haystack, String needle, StringComparison comparison) { if( String.Equals( haystack, needle, comparison ) ) return true; Int32 idx = 0; while( idx + needle.Length <= haystack.Length ) { idx = haystack.IndexOf( needle, idx, comparison ); if( idx == -1 ) return false; Int32 end = idx + needle.Length; // Needle must be enclosed in whitespace or be at the start/end of string Boolean validStart = idx == 0 || Char.IsWhiteSpace( haystack[idx - 1] ); Boolean validEnd = end == haystack.Length || Char.IsWhiteSpace( haystack[end] ); if( validStart && validEnd ) return true; idx++; } return false; } 

HtmlAgilityPack是为了提供一个DOM接口(例如createElementgetElementById等)的实现,但是现在已经有点落后了,并且缺less像classList这样的新的DOM特性,这会使得这个微不足道。

…我可能可以提交修改请求,但是HtmlAgilityPack没有官方的GitHub仓库。

你可以通过在你的Xpath查询中使用'contains'来解决你的问题,如下所示:

 var allElementsWithClassFloat = _doc.DocumentNode.SelectNodes("//*[contains(@class,'float')]") 

要在一个函数中重复使用,请执行以下操作:

 string classToFind = "float"; var allElementsWithClassFloat = _doc.DocumentNode.SelectNodes(string.Format("//*[contains(@class,'{0}')]", classToFind)); 
 public static List<HtmlNode> GetTagsWithClass(string html,List<string> @class) { // LoadHtml(html); var result = htmlDocument.DocumentNode.Descendants() .Where(x =>x.Attributes.Contains("class") && @class.Contains(x.Attributes["class"].Value)).ToList(); return result; } 

我在项目中使用了这种扩展方法。 希望它会帮助你们中的一个。

 public static bool HasClass(this HtmlNode node, params string[] classValueArray) { var classValue = node.GetAttributeValue("class", ""); var classValues = classValue.Split(' '); return classValueArray.All(c => classValues.Contains(c)); } 

您可以使用以下脚本:

 var findclasses = _doc.DocumentNode.Descendants("div").Where(d => d.Attributes.Contains("class") && d.Attributes["class"].Value.Contains("float") );