解析具有大量节点的XML文件

时间:2015-07-08 17:51:31

标签: php xml xpath xml-parsing

我有一个XML Feed,其中包含以下网址,其中包含要检索的行程ID。

http://www.expeditiontrips.com/xml/triplist.xml

根据每次旅行,可以从以下URL中检索信息,其中ID成为XML名称

http://www.expeditiontrips.com/xml/trips/3481.xml

现在,如果您查看http://www.expeditiontrips.com/xml/trips/3481.xml链接,您可以看到添加节点下添加了一个名为" JRO Teaser"的标签。我需要做的是解析这两个文件,并显示有这个" JRO Teaser"标签。包括此次增加的旅行是折扣旅行。我编写了一个代码,它可以检索列表,但问题是因为第一个XML文件中有518个节点,它需要花费5分钟来加载页面。换句话说,由于大号没有,它花费了太多时间来显示结果。旅行。有人可以为我提供一种正确显示这一点的方法,而无需太多的加载时间。以下是我的代码。

    <?php 
        $ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $xml_raw = curl_exec($ch);
        curl_close($ch);

        $trips = simplexml_load_string($xml_raw);

        $total = count($trips);

        for($a=0; $a<=$total; ++$a) { 

            $ch = curl_init('http://www.expeditiontrips.com/xml/trips/' . $trips->trip[$a] . '.xml');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $xml_raw = curl_exec($ch);
            curl_close($ch);

            $info = simplexml_load_string($xml_raw);

            //print_r($info);

            $name = 'JRO Teaser';

            $tripss = $info->xpath("/trip/additions/addition/label");

            if($tripss[1] == 'JRO Teaser') {

                echo $info->code; 

            } 

        }       
    ?>

2 个答案:

答案 0 :(得分:1)

您正在尝试处理平均大小为18-25KB的500多个xml文档 对我来说,每篇文档需要0.5-1秒。

如果您的业务逻辑允许,我建议您在页面加载之外执行此操作,例如在cron作业中,每30分钟或1小时执行此操作,并将结果保存在服务器上的数据库甚至文本文件中。 / p>

你可以在更高的频率下进行,具体取决于你所追求的,例如。跳过已经处理过的id或类似注释中的内容。

在实际页面加载时,只需查询存储空间,平面文件或数据库。

稍微改变了你的代码:     

$trips = simplexml_load_file('http://www.expeditiontrips.com/xml/triplist.xml');

foreach ($trips as $tripId) {

    $info = simplexml_load_file('http://www.expeditiontrips.com/xml/trips/' . $tripId .'.xml');

    $name = 'JRO Teaser';

    foreach ($info->additions->addition as $add)
        if ($add->label==$name) $codes[] = (string)$info->code;

}

// process the $codes array, save to text file or database
// saveCodes($codes);
print_r($codes);

答案 1 :(得分:1)

当然,你可以通过向它投掷机器电源来解决这个问题 - 或者只是要求解析正确的文档。

JRO很可能代表刚刚发布的优惠。您可以通过将HTML文档加载到 DOMDocument 并使用一些xpath来获取这些列表:

$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($buffer);
libxml_use_internal_errors($saved);
$doc->formatOutput = true;
$doc->preserveWhiteSpace = false;

$xpath = new DOMXPath($doc);
$ids = $xpath->query('//section/article[@class="sr search_result"]//input[@class="tc"]/@value');
foreach ($ids as $id) {
    echo $id->nodeValue, "\n";
}

因此,不是查询您自己的所有文档,而是查询已经为您查询的网站。

缓存规则仍适用于此处。这有助于像你一样开发这种刮刀。

$url = 'http://www.expeditiontrips.com/jro-list/?region=all&pricerange=special';
$key = 'scratch_3_' . md5($url);
if (file_exists($key)) {
    $buffer = file_get_contents($key);
} else {
    $buffer = file_get_contents($url);
    file_put_contents($key, $buffer);
}

输出:

3770
3025
3667
3781
3571
3078
3431
3433
3382
3173
3944
3887
3890
3731
2779
3313
3901
3900
3896
3430
3882
3884
2991
3777
3181
3921
3869
3935
3873
3923
3788
3789
3785
3786
3864
3927
3926
3054
3792
3793
3528
3928
3929
3930
3780
3790
3922
3810
3291
3796
3231
3835
2901
2883
3918
3815
3807
3808
3809
3919
3269
3734
3735
3718
3736
3904
3916
3917
3806
2548
3530
3760
2093
2704
3444
3489
3773
3772
2841
2842
3797
3932
2889
3891
3894
3895
3481
3938
3521
2547
3547
3589
3872
3939
3940
3620
3879
3545
3259
3933
2487
1831
3616
3188
3546
3838
3881
3749
3751
3131
3549
2806
3795
3062
3061
3931
3837
3142
1234
3799
2758
2490
3653
3068
3155
1929
2293
2975
2193
2923
3418
3122
2395
2846
2831
3119
3120
3802
2821
2820
3803
3801
3725
1555
3365
3228
3229
3204
3742
2410
3722
3412
3413
3174
3707
3434
3175
3383
3758
3631
3634
3679
3937
3870
3581
3897
3934
3778
3779
3924
3447
3583
3782
3768
3866
3548
3544
3821
3822
3925
相关问题