طلب العقد من معظم الصور؟
-
22-09-2019 - |
سؤال
قد يبدو هذا معقدًا بعض الشيء ، لكن ما أريد فعله هو العثور على كل شيء <a>
S التي تحتوي <img>
S بحيث يتم اختيار الصور الموجودة في نفس العقدة مع أكبر عدد من الصور الأخرى أولاً.
على سبيل المثال ، إذا كانت صفحتي تبدو هكذا:
http://img684.imageshack.us/img684/5678/imagechart.gif
إذا كانت المربعات الزرقاء <div>
S والمربعات الوردية <img>
ثم الوسط div
يحتوي على معظم الصور ، ثم يتم اختيار تلك الصور أولاً. نظرًا لأنهم لا يتداخلون أي أعمق من ذلك ، فإنهم يظهرون فقط في الترتيب الذي يكونون فيه على الصفحة. بعد ذلك ، يتم اختيار Div الأول (يحتوي على ثاني معظم الصور) ، وهكذا دواليك ... هل هذا منطقي؟
يمكننا أن نفكر في الأمر بشكل متكرر. لأول مرة 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]