用子元素分隔LI

时间:2013-06-12 17:24:40

标签: html-agility-pack

我有以下代码:

HtmlAgilityPack.HtmlNodeCollection nodeCollection = bodyNode.SelectNodes("//ul[@class='myClass']//li");

获得约250 LI

UL格式有点奇怪,它是这样的:

<ul>
    <li>
        <h5>Parent</h5>
        Some more tags here...
    </li>
    <li>
        <h4>Child of the prev li</h4>
    </li>
    <li>
        <h4>Child of the prev li</h4>
    </li>
    <!-- and so on -->
    <!-- Then again -->
    <li>
        <h5>Parent</h5>
        Some more tags here...
    </li>
    <li>
        <h4>Child of the prev li</h4>
    </li>
    <li>
        <h4>Child of the prev li</h4>
    </li>
    <!-- child li's are not constant, this is only for demo -->
</ul>

我需要将LI分成几组,其中每组包含父LI和所有子LI

任何人都可以帮忙解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

var tree = new Dictionary<HtmlNode, List<HtmlNode>>();
foreach (var node in nodeCollection)
    if (node.SelectSingleNode("h5[text()='Parent']") != null)
        tree.Add(node, new List<HtmlNode>());
    else
        tree.Last().Value.Add(node);

var groups = nodeCollection.Group();

static class Extensions
{
    public static ILookup<HtmlNode, HtmlNode> Group(this HtmlNodeCollection collection)
    {
        return collection.Where(n => !n.IsParent()).ToLookup(n => n.GetParent());
    }

    public static bool IsParent(this HtmlNode node, string header = "Parent")
    {
        var h = node.Element("h5");
        return h != null && h.InnerText == header;
    }

    public static HtmlNode GetParent(this HtmlNode node)
    {
        while (!node.IsParent())
            node = node.PreviousSibling;
        return node;
    }
}

答案 1 :(得分:0)

如果我理解正确,这就是你想要的

HtmlNodeCollection liList = doc.DocumentNode.SelectNodes("//ul//li");
List<List<HtmlNode>> liGroups = new List<List<HtmlNode>>();
List<HtmlNode> liGroup = null;
foreach (HtmlNode li in liList)
{
    if (li.InnerText.Contains("Parent"))
    {
        if (liGroup != null)
            liGroups.Add(liGroup);
        liGroup = new List<HtmlNode>();
        liGroup.Add(li);
    }
    else
    {
        liGroup.Add(li);
    }
}
liGroups.Add(liGroup);

最后您将拥有一个列表liGroups,其中包含其他列表liGroup。对于您的上述HTML,它会显示liGroups有2个liGroup,因为在您的上述HTML中,您有2个父母,而且两个liGroup将有3个li(1个父级+ 2个孩子),因为两个父母有相同数量的孩子。

之后,您可以随心所欲地使用它们,例如:

MessageBox.Show(liGroups[0][2].InnerText); //Show from the first group the 3rd's li InnerText