0

私は次のようなxp​​athを持っています:

$path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';

ここで$i、1からXになります。私は通常使用します:

for($i=1; $i<X;$i++){
  $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
  $nodelist = $xpath->query($path);
  $result = $nodelist->item(0)->nodeValue;
};

ただし、この場合、 Xがいくらかわかりません。Xを知らずにこれをループする方法はありますか?

4

4 に答える 4

5

なぜそれらをスタックしないのですか?(壊れやすいコード、チェックを追加)のようなもの:

// first xpath for the outer node-list
$tds = $xpath->query('//*[@id="page-content"]/table/tbody/tr[3]/td');
foreach ($tds as $td)
{
    // fetch the included values with a relative xpath to the current node
    $nodelist = $xpath->query('./div/a', $td);
    ...
}

そして実際には、最終的にノード値を照会する必要があるため、その内部ノードリストは必要ありません。ただし、これをここに残して、具象ノードを基準にしたxpathを使用して直接実行できることを示します。


したがって、IDが「page-content」のノード内の任意のテーブルの3番目の内部の任意の内部に最初の <a>要素が必要場合は、そのように直接書き込むことができます。これは1つのクエリです。 <div> <tr>

//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]

述語(角かっこ)は、接頭辞が付いたパス内のノードのみを対象としているため、[1]は、の唯一の場合とa同様に、最後のノードのみを対象としています。[3]tr

コード例:

$as = $xpath->query('//*[@id="page-content"]/table/tbody/tr[3]/td/div/a[1]');
foreach ($as as $a) 
{
    echo $a->nodeValue, "\n";
}

したがって、これにより単一のノードリストとして結果が得られ、2番目のxpathクエリを実行する必要はありません。

于 2012-11-09T15:25:49.010 に答える
2

私があなたの質問を理解しているなら、あなたは<td>あなたのXPathの下の要素の最大数までループする方法を尋ねていますか?

次を使用してノードの数を取得できます。

count(//*[@id="page-content"]/table/tbody/tr[3]/td)そしてそれを一時変数として保存し、次のように次のステートメントで使用します。

for($i=1; $i<numberOfTdElements;$i++){
  $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
  $nodelist = $xpath->query($path);
  $result = $nodelist->item(0)->nodeValue;
};

hakreの提案に応えて:

$tbody = $doc->getElementsByTagName('tbody')->item(0);

// our query is relative to the tbody node
$query = 'count(tr[3]/td)';

$tdcount = $xpath->evaluate($query, $tbody);
echo "There are $tdcount elements under tr[3]\n";

そして、それをすべて組み合わせます:

for($i=1; $i<$tdcount;$i++){
      $path = '//*[@id="page-content"]/table/tbody/tr[3]/td['.$i.']/div/a';
      $nodelist = $xpath->query($path);
      $result = $nodelist->item(0)->nodeValue;
    };
于 2012-11-09T15:27:01.197 に答える
0

あなたがやろうとしてaいるのは、の子であるすべての要素をフェッチすることだと思います。これは、 3divつおきの要素の子である任意のtd要素の子です。それが正しければ、このクエリでこれらを簡単に取得できます。 tr

<?php 

$doc = new DOMDocument();
$doc->loadXML( $xml );
$xpath = new DOMXPath( $doc );
$nodes = $xpath->query( '//*[@id="page-content"]/table/tbody/tr[3]/td/div/a' );
foreach( $nodes as $node )
{
    echo $node->nodeValue . '<br>';
}

$xmlこれに似たドキュメントはどこにありますか?

<?php

$xml = <<<XML
<?xml version="1.0" encoding="utf-8" ?>
<result>
    <div id="page-content">
        <table>
            <tbody>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                    <td>
                        <div><a>This one should be fetched</a></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div><a>This one shouldn't be fetched</a></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</result>
XML;

言い換えれば、これらすべてのtd要素をループする必要はありません。それらをすべて一度にフェッチできるため、DOMNodeList必要なすべてのノードが含まれます。

于 2012-11-09T15:33:18.003 に答える
0
$doc = new DOMDocument();

$doc->loadXML( $xml );

$xpath = new DOMXPath( $doc );

$nodes = $xpath->query( '/result/div[@id="page-content"]/table/tbody/tr[3]/td/div/a');

foreach( $nodes as $node )
{
    echo $node->nodeValue . '<br>';
}
于 2013-11-19T10:46:13.537 に答える