这可能听起来有点复杂,但我想要做的是找到包含<a>
的所有<img>
s,使得同一节点中的图像具有最多的其他图像首选。
例如,如果我的页面如下所示:
http://img684.imageshack.us/img684/5678/imagechart.gif
如果蓝色方块为<div>
s且粉红色方块为<img>
s,则中间div
包含最多图像,则首先选择这些图像。由于它们没有嵌套得更深,所以它们只是按照它们在页面上的顺序出现。接下来选择第一个div(包含第二个最多的图像),依此类推......这有意义吗?
我们可以递归地想到它。首先选择body
,因为它总是包含最多的图像,然后检查每个直接子项以查看哪个包含最多的图像后代(不一定是直接的),然后我们进入该节点,然后重复...
答案 0 :(得分:1)
您可以尝试查看每个节点的图像数量。
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; }
答案 1 :(得分:1)
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>
的{{1}}元素。
如果您只想查找带有后代<img>
元素的<a>
元素,请调整 for-each 中的 XPATH 以选择: <img>
答案 2 :(得分:0)
目前的解决方案:
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);
// ...
这有点效率低,但因为它做了大量的重述,但很好。