无法使用 HtmlAgilityPack 和 XPath 提取 <link> 元素

Cannot extract <link> element using HtmlAgilityPack and XPath

我正在使用 Html 敏捷包 select 从 rss xml 中输出文本数据。对于其他所有节点类型(title、pubdate、guid 等),我可以使用 XPath 约定 select 排除 inner-text,但是在查询“//link”或 "item/link" 时返回空字符串。

public static IEnumerable<string> ExtractAllLinks(string rssSource)
{
    //Create a new document.
    var document = new HtmlDocument();
    //Populate the document with an rss file.
    document.LoadHtml(rssSource);
    //Select out all of the required nodes.
    var itemNodes = document.DocumentNode.SelectNodes("item/link");
    //If zero nodes were found, return an empty list, otherwise return the content of those nodes.
    return itemNodes == null ? new List<string>() : itemNodes.Select(itemNode => itemNode.InnerText).ToList();
}

有人知道为什么这个元素的行为与其他元素不同吗?

附加:运行 "item/link" returns 零个节点。 运行 "//link" returns 正确的节点数但是内部文本的长度为零个字符。

使用下面的测试数据,使用“//name”returns "fred" 的单个记录但是使用“//link”的单个记录带有空字符串是返回。

<site><link>Hello World</link><name>Fred</name></site>

我肯定是因为这个世界"link"。如果我将其更改为 "linkz",它会完美运行。

以下解决方法非常有效。但是我想了解为什么搜索“//link”不像其他元素那样有效。

public static IEnumerable<string> ExtractAllLinks(string rssSource)
{
    rssSource = rssSource.Replace("<link>", "<link-renamed>");
    rssSource = rssSource.Replace("</link>", "</link-renamed>");
    //Create a new document.
    var document = new HtmlDocument();
    //Populate the document with an rss file.
    document.LoadHtml(rssSource);
    //Select out all of the required nodes.
    var itemNodes = document.DocumentNode.SelectNodes("//link-renamed");
    //If zero nodes were found, return an empty list, otherwise return the content of those nodes.
    return itemNodes == null ? new List<string>() : itemNodes.Select(itemNode => itemNode.InnerText).ToList();
}

如果你打印 DocumentNode.OuterHtml,你会看到问题:

var html = @"<site><link>Hello World</link><name>Fred</name></site>";
var doc = new HtmlDocument();
doc.LoadHtml(html);
Console.WriteLine(doc.DocumentNode.OuterHtml);

输出:

<site><link>Hello World<name>Fred</name></site>

link 恰好是一些 特殊标签 * 之一,被 HAP 视为自关闭标签。您可以通过在解析 HTML 之前设置 ElementsFlags 来更改此行为,例如:

var html = @"<site><link>Hello World</link><name>Fred</name></site>";
HtmlNode.ElementsFlags.Remove("link");  //remove link from list of special tags
var doc = new HtmlDocument();
doc.LoadHtml(html);
Console.WriteLine(doc.DocumentNode.OuterHtml);
var links = doc.DocumentNode.SelectNodes("//link");
foreach (HtmlNode link in links)
{
    Console.WriteLine(link.InnerText);
}

Dotnetfiddle Demo

输出:

<site><link>Hello World</link><name>Fred</name></site>
Hello World

*) link之外的特殊标签的完整列表,默认包含在ElementsFlags字典中,可以在源代码中看到HtmlNode.cs。其中一些最受欢迎的是<meta><img><frame><input><form><option>