Frage

Das mag ein bisschen kompliziert klingen, aber was ich tun möchte, ist alles zu finden <a>s, die enthalten <img>s So dass die Bilder, die im selben Knoten mit der größten Anzahl anderer Bilder sind, zuerst ausgewählt werden.

Zum Beispiel, wenn meine Seite so aussieht:

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

Wenn die blauen Quadrate sind <div>S und die rosa Quadrate sind <img>s dann die Mitte div Enthält die meisten Bilder, dann werden diese Bilder zuerst ausgewählt. Da sie nicht tiefer verschachtelt sind, werden sie nur in der Reihenfolge erscheinen, dass sie auf der Seite sind. Als nächstes wird die erste Div ausgewählt (enthält die zweithäufigsten Bilder) und so weiter ... macht das Sinn?

Wir können es irgendwie rekursiv vorstellen. Zuerst die body würde ausgewählt, da dies immer die meisten Bilder enthält, dann wird jedes der direkten Kinder untersucht, um herauszufinden, welche die meisten Bild -Nachkommen (nicht unbedingt direkt) enthält, dann gehen wir in diesen Knoten und wiederholen ...

War es hilfreich?

Lösung 3

Aktuelle Lösung:

    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);
        }
    }

Beispiel Verwendung:

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

Es ist jedoch ein bisschen ineffizient, weil es viel erzählt, aber na ja.

Andere Tipps

Sie könnten versuchen, die Anzahl von Bildern für jeden Knoten zu betrachten.

    public static XmlNode FindNodeWithMostImages(XmlNodeList

Knoten) {

        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 bietet nicht die Möglichkeit, eine Sammlung zu sortieren. Sie müssen nutzen XPath mit etwas anderem.

Hier ist ein Beispiel Xslt Lösung, die alle Elemente finden, die Nachkommen enthalten <img> Elemente und sortiert sie dann nach der Anzahl ihres Nachkommens <img> Elemente in absteigender Reihenfolge.

    <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>

Ich war mir nicht klar aus Ihrer Frage und Beispielen, ob Sie ein Element mit Nachkommen finden möchten <img> oder nur <a> mit Nachkommen <img>.

Wenn Sie nur finden wollten <a> Elemente mit Nachkommen <img> Elemente und dann die anpassen XPath in dem für jeden zur Auswahl: //a[descendant::img]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top