我有以下节点
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[7]/p[1]/#text[1]"
我怎样才能知道最后一个是最近的一个?
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[4]/div[1]/img[1]"
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[4]/div[3]/a[1]/img[1]"
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[4]/div[3]/a[2]/img[1]"
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[4]/div[5]/img[1]"
"/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[5]/div[1]/img[1]"
并不总是最后一个。
这是我到达那里的方式:
protected string GuessThumbnail(HtmlDocument document)
{
HtmlNode root = document.DocumentNode;
IEnumerable<string> result = new List<string>();
HtmlNode description = root.SelectSingleNode(DescriptionPredictiveXPath);
if (description != null) // in this case, we predict relevant images are the ones closest to the description text node.
{
HtmlNode node = description.ParentNode;
while (node != null)
{
string path = string.Concat(node.XPath, ImageXPath);
node = node.ParentNode;
IEnumerable<HtmlNode> nodes = root.SelectNodesOrEmpty(path);
// find the image tag that's closest to the text node.
if (nodes.Any())
{
var xpaths = nodes.Select(n => n.XPath);
xpaths.ToList();
// return closest
}
}
}
// figure some other way to do it
throw new NotImplementedException();
}
答案 0 :(得分:0)
考虑将“整个树中的位置按深度优先顺序”分配给每个节点。这样比较2个节点将非常简单。
如果您可以将任意数据附加到您的节点 - 直接添加它。否则有所有节点的字典来定位地图。
请注意,根据您需要进行此次比较的次数,此方法可能对您来说很慢,但应该很容易实现并根据您的要求进行衡量。
答案 1 :(得分:0)
是这样的:
protected string GuessThumbnail(HtmlDocument document)
{
HtmlNode root = document.DocumentNode;
HtmlNode description = root.SelectSingleNode(DescriptionPredictiveXPath);
if (description != null)
{
// in this case, we predict relevant images are the ones closest to the description text node.
HtmlNode parent = description.ParentNode;
while (parent != null)
{
string path = string.Concat(parent.XPath, ImageXPath);
IList<HtmlNode> images = root.SelectNodesOrEmpty(path).ToList();
// find the image tag that's closest to the text node.
if (images.Any())
{
HtmlNode descriptionOutermost = description.ParentNodeUntil(parent); // get the first child towards the description from the parent node.
int descriptionIndex = descriptionOutermost.GetIndex(); // get the index of the description's outermost element.
HtmlNode closestToDescription = null;
int distanceToDescription = int.MaxValue;
foreach (HtmlNode image in images)
{
int index = image.ParentNodeUntil(parent).GetIndex(); // get the index of the image's outermost element.
if (index > descriptionIndex)
{
index *= -1;
}
int distance = descriptionIndex - index;
if (distance < distanceToDescription)
{
closestToDescription = image;
distanceToDescription = distance;
}
}
if (closestToDescription != null)
{
string source = closestToDescription.Attributes["src"].Value;
return source;
}
}
parent = parent.ParentNode;
}
}
// figure some other way to do it
throw new NotImplementedException();
}
public static HtmlNode ParentNodeUntil(this HtmlNode node, HtmlNode parent)
{
while (node.ParentNode != parent)
{
node = node.ParentNode;
}
return node;
}
public static int GetIndex(this HtmlNode node)
{
return node.ParentNode.ChildNodes.IndexOf(node);
}