Вопрос

Это может звучать немного сложно, но я хочу найти все <a>S, которые содержат <img>S так, что изображения, которые находятся в одном узле с наибольшим количеством других изображений, первыми выбираются.

Например, если моя страница выглядит так:

http://img684.imageshack.us/img684/5678/imagechart.gif

Если синие квадраты <div>S и розовые квадраты <img>S затем середина div Содержит большинство изображений, затем сначала выбираются эти изображения. Поскольку они не вложены глубже, они просто появляются в том порядке, в котором они находятся на странице. Далее выбран первый Div (содержит 2 -е место в большинстве изображений), и так далее ... это имеет смысл?

Мы можем думать об этом вроде рекурсивно. Сначала body будет выбран, так как это всегда будет содержать большинство изображений, тогда каждый из прямых детей исследуется, чтобы увидеть, что содержит наибольшее количество потомков (не обязательно прямое), тогда мы переходим в этот узел и повторяем ...

Это было полезно?

Решение 3

Текущее решение:

    private static int Count(HtmlNodeCollection nc) {
        return nc == null ? 0 : nc.Count;
    }

    private static void BuildList(HtmlNode node, ref List<HtmlNode> list) {
        var sortedNodes = from n in node.ChildNodes
                          orderby Count(n.SelectNodes(".//a[@href and img]")) descending
                          select n;
        foreach (var n in sortedNodes) {
            if (n.Name == "a") list.Add(n);
            else if (n.HasChildNodes) BuildList(n, ref list);
        }
    }

Пример использования:

    private static void ProcessDocument(HtmlDocument doc, Uri baseUri) {
        var linkNodes = new List<HtmlNode>(100);
        BuildList(doc.DocumentNode, ref linkNodes);
        // ...

Это немного неэффективно, потому что он много рассказывает, но хорошо.

Другие советы

Вы можете попробовать посмотреть на количество изображений для каждого узла.

    public static XmlNode FindNodeWithMostImages(XmlNodeList

узлы) {

        var greatestImageCount = 0;
        XmlNode nodeWithMostImages = null;

        foreach (XmlNode node in nodes)
        {
            var currentNode = node;
            var currentNodeImageCount = node.SelectNodes("*/child::img").Count;

            if (currentNodeImageCount > greatestImageCount)
            {
                greatestImageCount = currentNodeImageCount;
                nodeWithMostImages = node;
            }
        }

        return nodeWithMostImages;
    }

Xpath 1.0 не дает возможности сортировать коллекцию. Вам нужно будет использовать Xpath с чем -то еще.

Вот пример XSLT Решение, которое найдет все элементы, которые содержат потомки <img> элементы, а затем сортируют их по подсчету их потомка <img> Элементы в порядке убывания.

    <xsl:template match="/">
        <!--if only want <a>, then select //a[descendant::img] -->
        <xsl:for-each select="//*[descendant::img]">
            <xsl:sort select="count(descendant::img)" order="descending" />

                <!--Example output to demonstrate what elements have been selected-->
                <xsl:value-of select="name()"/><xsl:text> has </xsl:text>
                <xsl:value-of select="count(.//img)" />  
                <xsl:text> descendant images                     
                </xsl:text>

        </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

Мне не было ясно из вашего вопроса и примеров, хотите ли вы найти какой -нибудь элемент с потомком <img> или просто <a> с потомком <img>.

Если вы хотите просто найти <a> Элементы с потомком <img> элементы, затем отрегулируйте Xpath в для каждого выбирать: //a[descendant::img]

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top