나는 다음과 같이 구성된 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>
<span>
태그의 값에 따라 해당 string
에 대한 <strong>
태그의 값을 구문 분석해야합니다.
나는 다음과 같은 것을 가지고있다.
String vintage;
String sugar;
String abv;
현재 beverageFacts
-node의 각 자식 노드를 루핑하여 값을 검사하여 올바른 해당 string
로 구문 분석 string
. 지금까지 "Vintage"값을 얻으려는 코드는 다음과 같지만 결과는 항상 null
입니다.
HtmlNodeCollection childNodes = bevFactNode.ChildNodes;
foreach (HtmlNode subNode in childNodes)
{
if (subNode.InnerText.TrimStart() == "Vintage")
vintage = subNode.NextSibling.InnerText.Trim();
}
내 노드 선택이 잘못되었다고 생각하지만 가장 효율적인 방법으로 제대로 수행하는 방법을 알 수는 없습니다.
이것을 달성하기위한 쉬운 방법이 있습니까?
2013 년 7 월 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 마크 업을 보면 노드에서 충분히 깊숙이 가지 않았다는 것을 알았습니다. 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을 디코딩하여 결과의 형식을 올바르게 지정합니다.
교훈!
요약하면 가장 좋은 해결책은 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;