Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's the plan, select all the <code>seperator</code> elements then find all consecutive sibling elements with the desired class.</p> <p>Unfortunately, there is no simple way to get a collection of siblings in the current versions of HTML Agility Pack, you only have access to the (one) next sibling. It's hard to collect data from linked structures nicely using LINQ. And since there is no real hierarchy in the HTML, this would be somewhat of a challenge.</p> <p>If you have XPath available, you can use the <code>following-sibling</code> axis to get all following sibling elements in conjunction with the <code>TakeWhile()</code> method to do the following:</p> <pre class="lang-cs prettyprint-override"><code>var htmlStr = @"&lt;li class = ""seperator""&gt; a date &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt; &lt;li class = ""seperator""&gt; a new date &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt; &lt;li class = ""seperator""&gt; a nother new date &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt; &lt;li class = ""lol""&gt; some text &lt;/li&gt;"; var doc = new HtmlDocument(); doc.LoadHtml(htmlStr); var data = from li in doc.DocumentNode.SelectNodes("li[@class='seperator']") select new { Separator = li.InnerText, Content = li.SelectNodes("following-sibling::li") .TakeWhile(sli =&gt; sli.Attributes["class"].Value == "lol") .Select(sli =&gt; sli.InnerText) .ToList(), }; </code></pre> <hr> <p>Otherwise if you don't have XPaths available, you can create an enumerable from any linked structure with the following:</p> <pre class="lang-cs prettyprint-override"><code>public static class Extensions { public static IEnumerable&lt;TSource&gt; ToLinkedEnumerable&lt;TSource&gt;( this TSource source, Func&lt;TSource, TSource&gt; nextSelector, Func&lt;TSource, bool&gt; predicate) { for (TSource current = nextSelector(source); predicate(current); current = nextSelector(current)) yield return current; } public static IEnumerable&lt;TSource&gt; ToLinkedEnumerable&lt;TSource&gt;( this TSource source, Func&lt;TSource, TSource&gt; nextSelector) where TSource : class { return ToLinkedEnumerable(source, nextSelector, src =&gt; src != null); } } </code></pre> <p>Then your query now becomes this:</p> <pre class="lang-cs prettyprint-override"><code>var data = from li in doc.DocumentNode.Elements("li") where li.Attributes["class"].Value == "seperator" select new { Separator = li.InnerText, Content = li.ToLinkedEnumerable(sli =&gt; sli.NextSibling) .Where(sli =&gt; sli.Name == "li") .TakeWhile(sli =&gt; sli.Attributes["class"].Value == "lol") .Select(sli =&gt; sli.InnerText) .ToList(), }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload