論理ANDを使用した 'HTMLアジリティパック' XPathクエリ

c# html-agility-pack xpath

質問

私はテキストを含む3列を含む最初の2行でHTML文書の表を検索しようとしています。

私はテーブルの最初の2行に最初の列のテキストが含まれているノードを返す、次のクエリを使用しようとしました:

string xpath = @"//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]";
HtmlNode temp = doc.DocumentNode.SelectSingleNode(xpath);

それは正常に動作しません、月。

ここでは、一致するようにしようとしているテーブルのサンプルHTMLをいくつか示します。

    <table width="100%" cellpadding="0" border="0">
       <tbody>
       <tr>
          <td width="27%" valign="center"><b><font size="1" face="Helvetica">SOME TEXT<br></font></b></td>
          <td width="1%"></td>
          <td width="9%" valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td width="1%"></td>
          <td width="25%" valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td width="37%"></td>
       </tr>
       <tr>
          <td valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td></td>
          <td valign="center"><font size="1" face="Helvetica">1<br></font></td>
          <td></td>
          <td valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td></td>
       </tr>
       </tbody>
</table>

列1,3,5に最初の2行にテキストがあることがわかります。それが私がマッチさせようとしているものです。

受け入れられた回答

//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]

このXPath式には多くの問題があります

  1. //table//table任意の選択tableの子孫であるtable 。ただし、提供されるXML文書にはネストした表はありません。

  2. table[//tr[1]//td[1]//*[contains(text(), *)] 。述語の中の//tr絶対 Xpath式です。この要素によってルートされるサブツリーだけでなく、 文書全体のすべてのtr要素が選択されtable 。ほとんどの場合、 //tr代わりに.//tr必要です。

  3. //td[1]は親の最初のtd子である任意のtd要素を選択しますが、おそらく最初の子孫td要素だけが必要です。その場合、このXPath式を使用する必要があります: (//td)[1]

  4. //*[contains(text(), *)]これは、その最初のテキストノードの子は、最初の子要素の文字列値を含む任意の要素を選択します-しかし、あなたは、単にことを確認したいtd子孫テキスト子ノードを持っています-これは正しく選択することができます: td[.//text()]

これらすべての問題の修正を組み合わせることで、おそらくあなたが望むのは次のようなものです

  //table
     [(.//tr)[1]/td[1][.//text()]
    and
      (.//tr)[2]/td[1][.//text()]
     ]

あるいは、同等ではあるが理解しやすく、エラーの起こりやすい表現を以下のように記述することもできます。

//table
  [descendant::tr[1]/td[1][descendant::text()]
 and
   descendant::tr[1]/td[1][descendant::text()]
  ]


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