How can I get all sibling ul tags?

html-agility-pack

Question

Here's an HTML snippet: from : http://www.sphere-light.com/compatibility/maker/id/4/

<h3 class="my-subject">a</h3>

<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>

<h3 class="my-subject">b</h3>

<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>
<ul class='ex'>....</ul>

How can I get just the 6 siblings ul.ex via <h3 class="my-subject">a</h3>

and get the next 6 ul via <h3 class="my-subject">b</h3>?

Accepted Answer

Since the number of <ul> tags can vary here's a couple of approaches you could take.

Using XPath:

var h3Xpath = "//h3[@class='my-subject']";
var query = doc.DocumentNode.SelectNodes(h3Xpath);
foreach (var h3 in query)
{
    var value = h3.InnerText;
    var ulXpathFmt = "following-sibling::ul[@class='ex' and " +
        "preceding-sibling::h3[@class='my-subject'][1]='{0}']";
    var uls = h3.SelectNodes(String.Format(ulXpathFmt, value));
    // do something with the uls
}

I generally wouldn't do it all using XPath alone but mixed in using some LINQ as well.

var h3Xpath = "//h3[@class='my-subject']";
var query = doc.DocumentNode.SelectNodes(h3Xpath);
foreach (var h3 in query)
{
    var ulXpath = "following-sibling::*";
    var uls = h3.SelectNodes(ulXpath)
        .TakeWhile(tag => tag.Name == "ul" &&
                          tag.Attributes["class"].Value == "ex");
    // do something with the uls
}



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why