ほとんどの画像に基づいてノードを並べ替えますか?
-
22-09-2019 - |
質問
少し複雑に聞こえるかもしれませんが、私がやりたいのはすべてを見つけることです <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]