Xpath所有跟随兄弟姐妹

时间:2014-11-13 23:23:56

标签: html xpath

我正在使用DOMXpath查询另一个站点上的表。我想要做的是获取表并以XML格式布局信息。

以下是我想从收集信息的表格(注意:有不同数量的玩家,但每位玩家的信息量相同)

<table id="report" cellspacing="0">
    <tbody>
        <tr>
            <td colspan="4" style="font-weight:bold;"> TEAM 1</td>
        </tr>
        <tr>
            <td>Player 1</td>
            <td>Average</td>
            <td>Other info</td>
            <td>More info</td>
        </tr>
        <tr>
            <td>Player 2</td>
            <td>Average</td>
            <td>Other info</td>
            <td>More info</td>
        </tr>
        ...
        <tr>
            <td colspan="22" style="font-weight:bold;"> TEAM 2</td>
        </tr>
        <tr>
            <td>Player 1</td>
            <td>Average</td>
            <td>Other info</td>
            <td>More info</td>
        </tr>
        <tr>
            <td>Player 2</td>
            <td>Average</td>
            <td>Other info</td>
            <td>More info</td>
        </tr>
        ...
    </tbody>
</table>

我的PHP到目前为止如下:

include 'simple_html_dom.php';
$dom = new DOMDocument();
@$dom->loadHTMLFile('table.html');
$xpath = new DOMXPath($dom);

$league = $xpath->query('//table[7]/tbody/tr/td[contains(@style,"bold")]');

$xml = new DOMDocument();

foreach($league as $teams) {
    $team = $xml->appendChild($xml->createElement("team"));

    $teamname = $xpath->query('.', $teams)->item(0)->nodeValue;
    $team->appendChild($xml->createElement("teamname", $teamname));

    $members = $xpath->query('../following-sibling::tr', $teams);

    foreach($members as $player) {

        $member = $team->appendChild($xml->createElement("member"));

        $name = $xpath->query('./td[1]', $player)->item(0)->nodeValue;
        $member->appendChild($xml->createElement("name", $name));
    }

}

echo $xml->saveXML();

我想将其保存为XML格式,如下所示:

<team>
    <teamname>Team 1</teamname>
    <member>
        <name>Player 1</name>
        <average>Average</average>
        <stats-one>Other info</stats-one>
        <stats-two>More info</stats-two>
    </member>
    <member>
        <name>Player 2</name>
        <average>Average</average>
        <stats-one>Other info</stats-one>
        <stats-two>More info</stats-two>
    </member>
    ...
<team>
<team>
    <teamname>Team 2</teamname>
    <member>
        <name>Player 1</name>
        <average>Average</average>
        <stats-one>Other info</stats-one>
        <stats-two>More info</stats-two>
    </member>
    <member>
        <name>Player 2</name>
        <average>Average</average>
        <stats-one>Other info</stats-one>
        <stats-two>More info</stats-two>
    </member>
    ...
<team>
编辑:我写了一个在某种程度上有效的foreach。我得到了我想要的信息,但它并没有在下一个团队开始之前就停止,而是它获得了每一个td,然后继续进入下一个团队并从taht point等获得每个td等等。 在每个团队的最后,信息的价值为&#34; Team Totals&#34;。我希望foreach在那之前停下来。 我尝试过与Oleksii Matiiasevych建议类似的东西,但它只是给了我团队中的第一个成员。

foreach($members as $player) {

        $member = $team->appendChild($xml->createElement("member"));

        $name = $xpath->query('./td[1]', $player)->item(0)->nodeValue;
        $member->appendChild($xml->createElement("name", $name));

        if($name = "Team Totals") break;
    }

1 个答案:

答案 0 :(得分:1)

首先你需要迭代成员$members = $xpath->query('../following-sibling::tr', $teams);,但只有2次因为只有2个玩家(以及更多的玩家):

for($i=0;$i<2;$i++) {
    // inside this loop.
}

在此循环中,您需要像在$member = $team->appendChild($xml->createElement("member"));之前那样创建成员节点(因此它将被创建2次),然后访问当前播放器$player = $members->item($i);,然后您可以访问此播放器属性{ {1}}之后,您需要为4个属性创建节点,最后相应地添加$playerAttrs = $xpath->query('./td', $player);之一。

编辑:如果玩家数量未知,那么迭代解决方案会有所改变:

$playerAttrs->item(0|1|2|3)->nodeValue

仍然需要为每个播放器属性指定某种名称,因为输入xml中没有此类信息。或者,如果您对foreach($members as $player) { $playerAttrs = $xpath->query('td', $player); if ($playerAttrs->length == 1) { break; // Break on next Team Name node } $member = $team->appendChild($xml->createElement("member")); // not sure part $statCounter = 0; foreach($playerAttrs as $attr) { $member->appendChild($xml->createElement("stats-{$statCounter}", $attr->nodeValue)); $statCounter++; } // end of not sure part } <stats-1>等感到满意,那么循环的结尾可能会显示在<stats-2>中。