特定のキーワードを含むテーブルを選択する方法 - c# - xpath - htmlagilitypack

c# html-agility-pack keyword select xpath

質問

クラスやIDを持たない製品ページから情報を収集する必要があります。私はhtmlagilitypackとC#4.0を使用しています。

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

以下のxpathはすべてのテーブルを選択します

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

以下のコードはテーブルを選択しますが、ほとんどの外部テーブルから開始します。私はその与えられた文字列を含む最も内側のテーブルを選択する必要があります

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

c#、xpath、htmlagilitypack

受け入れられた回答

以下のコードはテーブルを選択しますが、ほとんどの外部テーブルから開始します。私はその与えられた文字列を含む最も内側のテーブルを選択する必要があります

使用

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

これは、XMLドキュメント内でtable子孫を持たず、文字列" KDV"を含むテキストノードの子孫を持つtableを選択しtable

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

それらのうちの1つだけを選択したい場合は(最初のものを言う)、このXPath式を使用します- かっこに注意してください

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

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

//someName[1]

これは、XPathの2番目によくある質問です(デフォルトの名前空間を持つXML文書内の接頭辞のない名前を持つ要素を選択する方法の後にあります)。

上記の式は実際にドキュメント内のsomeName要素、つまりその親の最初の子を選択して試します。

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

存在する場合は、最初のsomeName要素(任意のXML文書内)のみを実際に選択する正しい式は次のsomeNameです。

(//someName)[1]

ここで、角括弧は、デフォルトのXPath演算子優先順位を明示的にオーバーライドするために使用されます。


人気のある回答

より効率的な方法があるかもしれません。とにかく、これは私があなたのケースで使用したコード全体であり、それは私のために働く:

        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);


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ