質問

少し複雑に聞こえるかもしれませんが、私がやりたいのはすべてを見つけることです <a>を含む <img>最も多くの他の画像と同じノード内にある画像が最初に選択されるようにします。

たとえば、私のページが次のようになっているとします。

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

青い四角が表示されている場合は、 <div>s とピンクの四角は <img>それから真ん中 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