在 PHP 中使用 XMLReader 读取子节点

Reading child nodes with XMLReader in PHP

背景:我有一个从资源 material 和 m.sarna.net 收集的恒星系统列表。该数据使用不同的 PHP 文件转换为 xml 文件,此处不予讨论。我正在从浏览器调用下面的 php 文件,传递名称和长度变量。我正在尝试使用 XMLReader 来定位特定节点以进行检索,但返回的数据太多了。我没有返回一个元素,然后继续下一个元素,而是重复获得相同的元素,如果我愿意的话,可以达到数千个。它应该很简单,但我不知道我错过了什么。请帮忙。如果您有兴趣,这是为 Battletech 准备的。虽然此文件有 7889 条跳跃路径,但包含双跳的文件,距离可达 60 光年,包含大约 24000 个条目,因此文件大小约为 4MB。每次需要时我都不想读入内存。

<jumpPathsStandard summary="Unique Jump Paths under 30 light years: 7889">
        <Terra>
                <from>Terra</from>
                <to>Thorin</to>
                <distance>24.35</distance>
                <fromX>0.00</fromX>
                <fromY>0.00</fromY>
                <toX>-23.73</toX>
                <toY>8.08</toY>
        </Terra>
        <Terra>
                <from>Terra</from>
                <to>Yorii</to>
                <distance>22.47</distance>
                <fromX>0.00</fromX>
                <fromY>0.00</fromY>
                <toX>-8.08</toX>
                <toY>21.39</toY>
        </Terra>
        <Terra_Firma>
                <from>Terra Firma</from>
                <to>Woodstock</to>
                <distance>22.36</distance>
                <fromX>22.69</fromX>
                <fromY>-33.90</fromY>
                <toX>44.60</toX>
                <toY>-37.03</toY>
        </Terra_Firma>
        <Tetersen>
                <from>Tetersen</from>
                <to>Tharkad</to>
                <distance>12.53</distance>
                <fromX>-204.99</fromX>
                <fromY>146.05</fromY>
                <toX>-215.94</toX>
                <toY>152.83</toY>
        </Tetersen>


$i=0;
if(isset($_GET["name"]) && isset($_GET["length"])) {
        switch ($_GET["length"]) {
                case "short":
                        $xml = new XMLReader();
                        $xml->open($shortfile);
                        $items = array();
                        while($xml->read() && $xml->name !== $_GET['name']);
                        while($xml->name === $_GET['name']) {
                                $item = array();
                                $node = new SimpleXMLElement($xml->readOuterXML());
                                if($node->from == $_GET['name']) {
                                        echo $i.":      ".$node->from." | ".$node->to." | ".$node->distance." | ".$node->fromX." | ".$node->fromY." | ".$node->toX." | ".$node->toY."<br>";
                                        $i++;
                                }
                        }
                        $xml->$close();
                break;
                case "long":
                        # Future use;
                break;
        }
}

我得到的输出: 测试

0:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08

1:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08

2:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08

3:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08

4:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08

5:泰拉 |索林 | 24.35 | 0.00 | 0.00 | -23.73 | 8.08 ...

您缺少在读取循环中移动到下一项的代码

$xml->next($_GET['name']);

所以...

while($xml->name === $_GET['name']) {
    $item = array();
    $node = new SimpleXMLElement($xml->readOuterXML());
    if($node->from == $_GET['name']) {
        echo $i.":      ".$node->from." | ".$node->to." | ".$node->distance." | ".$node->fromX." | ".$node->fromY." | ".$node->toX." | ".$node->toY."<br>";
        $i++;
    }

    // Next item...
    $xml->next($_GET['name']);
}
$xml->$close();