4

htmlCleaner に入れているこの xPath 式があります。

 //table[@class='StandardTable']/tbody/tr[position()>1]/td[2]/a/img

さて、私の問題はそれが変更され、 /a/img 要素が存在しない場合があることです。だから私はすべての要素を取得する式が欲しい

//table[@class='StandardTable']/tbody/tr[position()>1]/td[2]/a/img

/a/img が存在する場合、および

//table[@class='StandardTable']/tbody/tr[position()>1]/td[2]

/a/img が存在しない場合。

誰もこれを行う方法を知っていますか? 私はそれが私を助けるかもしれないと思われる何かを別の質問で見つけました

descendant-or-self::*[self::body or self::span/parent::body]

しかし、私はそれを理解していません。

4

3 に答える 3

4

使用する:

 (//table[@class='StandardTable']
     /tbody/tr)
         [position()>1]
                   /td[2]
                       [not(a/img)] 

|

 (//table[@class='StandardTable']
     /tbody/tr)
         [position()>1]
                   /td[2]
                      /a/img

一般に、$ns1ある条件$condが true の場合に 1 つのノード セット ( ) を選択し、それ以外の場合は別のノード セット ( $ns2) を選択する場合、次の単一の XPath 式で指定できます

$ns1[$cond] | $ns2[not($cond)]

この特定のケースでns1、次のとおりです。

 (//table[@class='StandardTable']
     /tbody/tr)
         [position()>1]
                   /td[2]
                      /a/img

ns2:

 (//table[@class='StandardTable']
     /tbody/tr)
         [position()>1]
                   /td[2]

そして$cond、次のとおりです。

boolean( (//table[@class='StandardTable']
         /tbody/tr)
             [position()>1]
                       /td[2]
                          /a/img
        )
于 2011-12-19T21:13:52.263 に答える
2

|2 つの相互に排他的な式の結合を選択できます (結合演算子に注意してください)。

//table[@class='StandardTable']/tbody/tr[position()>1]/td[2]/a/img|
//table[@class='StandardTable']/tbody/tr[position()>1]/td[2][not(a/img)]

最初の式がノードを返す場合、2 番目の式はノードを返しません (逆の場合も同様です)。つまり、必要なノードだけが常に取得されます。

@Dimitre の回答に対するコメントから、HTMLCleaner が XPath 1.0 を完全にサポートしていないことがわかります。あなたは本当にそれをする必要はありません。整形式でない入力を解析するには、HTMLCleaner が必要です。その仕事が終わったら、その出力を標準に変換し、org.w3c.dom.Documentそれを XML として扱います。

変換例を次に示します。

TagNode tagNode = new HtmlCleaner().clean("<html><div><p>test");
Document doc = new DomSerializer(new CleanerProperties()).createDOM(tagNode);

ここから先は、必要な実装で JAXP を使用してください。

XPath xpath = XPathFactory.newInstance().newXPath();
Node node = (Node) xpath.evaluate("/html/body/div/p[not(child::*)]", 
                       doc, XPathConstants.NODE);
System.out.println(node.getTextContent());

出力:

test
于 2011-12-19T21:15:17.837 に答える
0

これは醜く、うまくいかないかもしれませんが、原則は次のようにする必要があります。

//table[@class='StandardTable']/tbody/tr[position()>1]/td[2][exists( /a/img )]/a/img | //table[@class='StandardTable']/tbody/tr[position()>1]/td[2][not( exists( /a/img ) )]
于 2011-12-19T21:14:32.253 に答える