У меня есть 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>
-tags для соответствующей string
, в зависимости от того, какое значение имеет значение <span>
-tag.
У меня есть следующее:
String vintage;
String sugar;
String abv;
В настоящее время, я перекручивание через каждый дочерний узел beverageFacts
-node проверка значений разобрать его на правильную соответствующую 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
Я попытался удалить пробелы, как было предложено enricoariel, в комментариях, используя следующий код
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, я понял, что недостаточно углубляюсь в узлы. Кроме того, как отметил энрикоариэль, есть пробелы, которые я не чищу должным образом. Пропуская брата, который является пробелом, и вместо этого перейдем к следующему, я получаю правильный результат.
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, чтобы получить корректный результат.
Уроки выучены!
чтобы обобщить, я думаю, что лучшим решением будет удаление всех белых пробелов с использованием регулярного выражения до получения значения nextSibling:
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;