根据同级属性选择节点-HtmlAgilityPack-C#
本文关键字:选择 节点 -HtmlAgilityPack-C# 属性 | 更新日期: 2023-09-27 18:25:27
我有一个HTML文档,其结构如下
<ul class="beverageFacts">
<li>
<span>Vintage</span>
<strong>2007 </strong>
</li>
<li>
<span>ABV</span>
<strong>13,0 %</strong>
</li>
<li>
<span>Sugar</span>
<strong>5 gram/liter</strong>
</li>
我需要将<strong>
-标记的值解析为相应的string
,这取决于<span>
-标记的值。
我有以下内容:
String vintage;
String sugar;
String abv;
到目前为止,我正在循环遍历beverageFacts
节点的每个子节点,检查值以将其解析为正确的对应string
。到目前为止,我获得"Vintage"值的代码如下,尽管结果总是null
。
HtmlNodeCollection childNodes = bevFactNode.ChildNodes;
foreach (HtmlNode subNode in childNodes)
{
if (subNode.InnerText.TrimStart() == "Vintage")
vintage = subNode.NextSibling.InnerText.Trim();
}
我相信我对节点的选择是不正确的,但我不知道如何以最有效的方式正确地完成它。
有没有一种简单的方法可以实现这一点?
编辑2013-07-29
我已经尝试使用以下代码删除enricariel在评论中建议的空白
HtmlAgilityPack.HtmlDocument page = new HtmlWeb().Load("http://www.systembolaget.se/" + articleID);
string cleanDoc = Regex.Replace(page.DocumentNode.OuterHtml, @"'s*(?<capture><(?<markUp>'w+)>.*<'/'k<markUp>>)'s*", "${capture}", RegexOptions.Singleline);
HtmlDocument cleanPage = new HtmlDocument();
cleanPage.LoadHtml(cleanDoc);
结果仍然是
String vintage = null;
查看HTML标记,我意识到我在节点中做得不够深入。此外,正如enricoariel所指出的,有些白色空间我没有正确清洁。通过跳过作为空白的同级,而是跳到下面,我得到了正确的结果。
foreach (HtmlNode bevFactNode in bevFactsNodes)
{
HtmlNodeCollection childNodes = bevFactNode.ChildNodes;
foreach (HtmlNode node in childNodes)
{
foreach(HtmlNode subNode in node.ChildNodes)
{
if (subNode.InnerText.Trim() == "Årgång")
vintage = HttpUtility.HtmlDecode(subNode.NextSibling.NextSibling.InnerText.Trim());
}
}
}
Console.WriteLine("Vintage: " + vintage);
将输出
Vintage: 2007
我对HTML进行了解码,以获得正确格式的结果。
经验教训!
总之,我认为最好的解决方案是在检索下一个ibling值之前使用正则表达式剥离所有空白:
string myHtml =
@"
<ul class='beverageFacts'>
<li>
<span>Vintage</span>
<strong>2007 </strong>
</li>
<li>
<span>ABV</span>
<strong>13,0 %</strong>
</li>
<li>
<span>Sugar</span>
<strong>5 gram/liter</strong>
</li>";
//Remove space after and before tag
myHtml = Regex.Replace(myHtml, @"'s+<", "<", RegexOptions.Multiline | RegexOptions.Compiled);
myHtml = Regex.Replace(myHtml, @">'s+", "> ", RegexOptions.Compiled | RegexOptions.Multiline);
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(myHtml.Replace("/r", "").Replace("/n", "").Replace("/r/n", "").Replace(" ", ""));
doc.OptionFixNestedTags = true;
HtmlNodeCollection vals = doc.DocumentNode.SelectNodes("//ul[@class='beverageFacts']//span");
var myNodeContent = string.Empty;
foreach (HtmlNode val in vals)
{
if (val.InnerText == "Vintage")
{
myNodeContent = val.NextSibling.InnerText;
}
}
return myNodeContent;