gpt4 book ai didi

c# - 无法使用 HtmlAgilityPack 和 XPath 提取 元素

转载 作者:行者123 更新时间:2023-11-30 20:41:58 26 4
gpt4 key购买 nike

我正在使用 Html Agility 包从 rss xml 中选择文本数据。对于所有其他节点类型(标题、发布日期、guid 等),我可以使用 XPath 约定选择内部文本,但是在查询“//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”返回零个节点。运行“//link”返回正确数量的节点,但内部文本的长度为零个字符。

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

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

我确信这是因为世界“链接”。如果我将其更改为“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 视为自关闭标签。您可以通过设置 ElementsFlags 来更改此行为在解析 HTML 之前,例如:

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>

关于c# - 无法使用 HtmlAgilityPack 和 XPath 提取 <link> 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31830587/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com