2011-12-25 10 views
3

クラスやIDを持たない製品ページから情報を収集する必要があります。私はhtmlagilitypackとC#4.0を使用しています。特定のキーワードを含むテーブルを選択する方法 - c# - xpath - htmlagilitypack

この製品ページのソースコードには多くの表があります。価格テーブルには "KDV"という文字列が含まれています。だから私はこの "KDV"文字列を含む文字列を取得したいと思います。どうやってやるの ?

XPathは、以下の例

string srxPathOfCategory = "//table"; 
var selectedNodes = myDoc.DocumentNode.SelectNodes(srxPathOfCategory); 

コードは、以下のテーブルを選択するためのすべてのテーブルを選択するが、最も外側のテーブルから始まるであろう。私は、文字列

//table[contains(., ' KDV')] 

のC#、XPathの与えられた、htmlagilitypack

+0

CDVを意味しますか? –

+0

私はCDVが何であるか尋ねるかもしれませんか? – MonsterMMORPG

+0

コンマで区切られた値 –

答えて

4

次のコードは、テーブルを選択するが、最も外側のテーブルから始まります。

//table 
    [not(descendant::table) 
    and 
    .//text()[contains(., ' KDV')] 
    ] 

これはtable子孫を持たないXML文書内の任意のtableを選択し、それは持っている:私は与えられた文字列

使用ことを含んでいる最も内側のテーブルを選択する必要があります 文字列" KDV"を含むテキストノードの子孫です。

一般に、上記の式は、多くのそのようなtable要素を選択することができる。

あなたは(最初に言う)、このXPath式を使用し、選択し、それらを1つだけ必要な場合 - ブラケット気づくん:を覚えておいてください

(//table 
     [not(descendant::table) 
     and 
     .//text()[contains(., ' KDV')] 
     ] 
    )[1] 

:あなたが最初someNameを選択したい場合文書内の要素、(現在の受け入れ答えのように)これを使用することは間違っている:

//someName[1] 

これは、XPathで二番目のFAQ(あるものの後elemeを選択する方法デフォルトの名前空間を持つXML文書内の接頭辞のない名前を持つnts)。

上記の式は、実際にはドキュメント内の任意のsomeName要素を選択します。つまり、親の最初の子です。試してみてください。

この直感的でない動作の理由は、XPath []演算子が疑似演算子より高い優先順位(優先順位)を持つためです。

本当に(任意のXML文書で)のみ最初someName要素を選択し、正しい表現、そのようなものが存在する場合は、次のとおりです。ここで括弧を明示的にデフォルトのXPath演算子の優先順位を上書きするために使用されている

(//someName)[1] 

+0

私はあなたが最高だと言う必要があります:)このexperessionはそのテーブルを選択しています。ノードとしてのTDを選択するにはどうすればよいですか?ありがとうございます:http://pastebin.com/2hHxUHa8 – MonsterMMORPG

+0

@MonsterMMORPG:どうぞよろしくお願いいたします。テーブルのtdを選択するには、末尾に/ tdを追加するだけです。 '(// table [not(descendant :: table)と.// text()[contains(。、 'KDV')]])[1 ]/descendant :: td [1] 'はこのテーブルの最初の' td'を選択します。 –

1

はそれを行うには、より効率的な方法があるかもしれませんことを含んでいる最も内側のテーブルを選択する必要があります。とにかく、 これは私があなたのケースのために使用しているコード全体であり、それが私の作品:

 HtmlDocument doc = new HtmlDocument(); 
     string url = "http://www.pratikev.com/fractalv33/pratikEv/pages/viewProduct.jsp?pInstanceId=3138821"; 
     using (var response = (WebRequest.Create(url).GetResponse())) 
     { 
      doc.LoadHtml(new StreamReader(response.GetResponseStream()).ReadToEnd()); 
     } 
     /*There is an bug in the xpath used here. Should have been 
      (//table/tr/td/font[contains(.,'KDV')])[1]/ancestor::table[2] 
      See Dimitre's answer for an explanation and an alternative/
      more generic/(needless to say) better approach */ 
     string xpath = "//table/tr/td/font[contains(.,'KDV')][1]/ancestor::table[2]"; 
     HtmlNode table = doc.DocumentNode.SelectSingleNode(xpath); 
+0

これはヌルです: – MonsterMMORPG

+0

これはテーブルを選択しますが、ほとんどの外側から選択を開始します。私はテーブルを含むKDVの最初の親を意味する最も内側のテーブルを選択する必要があります:// table [contains(。、 'KDV')] – MonsterMMORPG

+0

そのソースコードはひどいです:http://pastebin.com/CrFCxdBh – MonsterMMORPG