2016-11-07 2 views
5

いくつかの値に対してHTMLレスポンスを解析し、それをSQLに挿入しようとしています。私は両方の値を取得することができますが、コードはforeach文でラップされているので、2回取得します。WebレスポンスからHTML値を取得する

ここに私のHTMLレスポンスここ

<div align="CENTER" class='dataTitle'>Host State Breakdowns:</div> 
<p align='center'> 
<a href='trends.cgi?host=hostname&includesoftstates=no&assumeinitialstates=yes&initialassumedhoststate=0&backtrack=4'><img src='trends.cgi?createimage&host=hostname&includesoftstates=no&initialassumedhoststate=0&backtrack=4' border="1" alt='Host State Trends' title='Host State Trends' width='500' height='20'></a><br> 
</p> 
<div align="CENTER"> 
<table border="0" class='data'> 
<tr><th class='data'>State</th><th class='data'>Type/Reason</th><th class='data'>Time</th><th class='data'>% Total Time</th><th class='data'>% Known Time</th></tr> 
<tr class='dataEven'><td class='hostUP' rowspan="3">UP</td><td class='dataEven'>Unscheduled</td><td class='dataEven'>0d 10h 5m 19s</td><td class='dataEven'>100.000%</td><td class='dataEven'>100.000%</td></tr> 
<tr class='dataEven'><td class='dataEven'>Scheduled</td><td class='dataEven'>0d 0h 0m 0s</td><td class='dataEven'>0.000%</td><td class='dataEven'>0.000%</td></tr> 
<tr class='hostUNREACHABLE'><td class='hostUNREACHABLE'>Total</td><td class='hostUNREACHABLE'>0d 0h 0m 0s</td><td class='hostUNREACHABLE'>0.000%</td><td class='hostUNREACHABLE'>0.000%</td></tr> 
<tr class='dataOdd'><td class='dataOdd' rowspan="3">Undetermined</td><td class='dataOdd'>Nagios Not Running</td><td class='dataOdd'>0d 0h 0m 0s</td><td class='dataOdd'>0.000%</td><td class='dataOdd'></td></tr> 
<tr class='dataOdd'><td class='dataOdd'>Insufficient Data</td><td class='dataOdd'>0d 0h 0m 0s</td><td class='dataOdd'>0.000%</td><td class='dataOdd'></td></tr> 
<tr class='dataOdd'><td class='dataOdd'>Total</td><td class='dataOdd'>0d 0h 0m 0s</td><td class='dataOdd'>0.000%</td><td class='dataOdd'></td></tr> 
<tr><td colspan="3"></td></tr> 
<tr class='dataEven'><td class='dataEven'>All</td><td class='dataEven'>Total</td><td class='dataEven'>0d 10h 5m 19s</td><td class='dataEven'>100.000%</td><td class='dataEven'>100.000%</td></tr> 
</table> 
</div> 
<br><br> 
<div align="CENTER" class='dataTitle'>State Breakdowns For Host Services:</div> 
<div align="CENTER"> 
<table border="0" class='data'> 
<tr><th class='data'>Service</th><th class='data'>% Time OK</th><th class='data'>% Time Warning</th><th class='data'>% Time Unknown</th><th class='data'>% Time Critical</th><th class='data'>% Time Undetermined</th></tr> 
<tr class='dataOdd'><td class='dataOdd'><a href='avail.cgi?host=hostname&service=servicename&t1=1478498400&t2=1478534719&backtrack=4&assumestateretention=yes&assumeinitialstates=yes&assumestatesduringnotrunning=yes&initialassumedhoststate=0&initialassumedservicestate=0&show_log_entries&showscheduleddowntime=yes&rpttimeperiod=24x7'>servicename</a></td><td class='serviceOK'>100.000% (100.000%)</td><td class='serviceWARNING'>0.000% (0.000%)</td><td class='serviceUNKNOWN'>0.000% (0.000%)</td><td class='serviceCRITICAL'>0.000% (0.000%)</td><td class='dataOdd'>0.000%</td></tr> 
<tr class='dataEven'><td class='dataEven'><a href='avail.cgi?host=hostname&service=servicename2&t1=1478498400&t2=1478534719&backtrack=4&assumestateretention=yes&assumeinitialstates=yes&assumestatesduringnotrunning=yes&initialassumedhoststate=0&initialassumedservicestate=0&show_log_entries&showscheduleddowntime=yes&rpttimeperiod=24x7'>servicename2</a></td><td class='serviceOK'>100.000% (100.000%)</td><td class='serviceWARNING'>0.000% (0.000%)</td><td class='serviceUNKNOWN'>0.000% (0.000%)</td><td class='serviceCRITICAL'>0.000% (0.000%)</td><td class='dataEven'>0.000%</td></tr> 
</table> 
</div> 

が私のコードです:

var response = (HttpWebResponse)request.GetResponse(); 
var stream = response.GetResponseStream(); 
HtmlDocument doc = new HtmlDocument(); 
doc.Load(stream); 

foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//table[@class]")) 
{ 

    foreach (HtmlNode node2 in node.SelectNodes("//td[@class = 'serviceOK']")) 
    { 
     var value = node2.InnerText; 
    } 

    foreach (HtmlNode node3 in node.SelectNodes("//a[contains(@href, 'avail.cgi')]")) 
    { 
     var name = node3.InnerText; 
    } 

} 

名はサービス名と値はクラスserviceOKを示して示していますが、それがために最初のforeachの自身を再度繰り返します。

私の結果は次のようになります。

100.000% (100.000%) 
100.000% (100.000%) 
servicename 
servicename2 
100.000% (100.000%) 
100.000% (100.000%) 
servicename 
servicename2 

、まず、値を一致させる方法はありますし、2つ、それらだけが一度表示されていますか?

答えて

3

最初のforeachは、最初のforeach文の中の他のforeach文の両方を実行するので、文書全体を走査します。
あなたのXPath式に一致する2つのテーブル要素があるので

"//table[@class]" 

あなたが二回あなたの答えを得ています。 XPath式、たとえば7と一致するテーブル要素がさらに多い場合は、結果を7回取得します。

テーブル内のテーブル行(tr)内にあるクラス "serviceOK"を持つすべてのテーブル分割(td)を見つけることができます。 このHtmlNodeを取得したら、サービス名を含む前の兄弟に行くことができます。

var response = (HttpWebResponse)request.GetResponse(); 
var stream = response.GetResponseStream(); 
HtmlDocument doc = new HtmlDocument(); 
doc.Load(stream); 

foreach (HtmlNode serviceOkNode in doc.DocumentNode.SelectNodes("//table[@class]/tr/td[@class = 'serviceOK']")) 
{ 
    HtmlNode serviceNameNode = serviceOkNode.PreviousSibling; 
    var value = serviceOkNode.InnerText; 
    var name = serviceNameNode.InnerText; 
} 
+0

ありがとうございました。私は最初のforeachが私を捨てていることを知っていましたが、私はSelectNodesに何を使う必要があるのか​​分かりませんでした。ありがとうございました – maltman