[英]How to process large XML files with jQuery/Javascript/PHP faster
我正在制作一個商店概述頁面,該頁面每頁呈現+-20種產品。 我從一個壓縮的(gzip)XML文件(* .xml.gz)中獲取數據。 這里是提要: http: //www.endclothing.com/media/end_feeds/awin_affiliates_eu.xml.gz每天一次,我使用PHP將文件下載到服務器上並提取XML文件。
問題是,解壓縮后的XML文件為+-60MB,其中包含超過5萬個產品。 現在,當我嘗試獲取產品並從XML文件顯示它們時,這進展非常緩慢。 用下面的代碼顯示本地XML的產品信息大約需要8秒鍾:
$.ajax({
type: "GET",
url: 'feeds/awin_affiliates_eu.xml',
cache: true,
dataType: "xml",
error: function (response) {
alert("An error occurred while processing XML file");
console.log('XML reading Failed: ', e);
},
success: function (response) {
var max = 20;
$(response).find("product").each(function (i) {
if (i < max) {
var _pid = $(this).find('pid').text();
var _mpn = $(this).find('mpn').text();
var _colour = $(this).find('colour').text();
var _name = $(this).find('name').text();
var _purl = $(this).find('purl').text();
var _instock = $(this).find('instock').text();
var _brand = $(this).find('brand').text();
var _suitable_for = $(this).find('suitable_for').text();
var _ptype = $(this).find('ptype').text();
var _category = $(this).find('category').text();
var _condition = $(this).find('condition').text();
var _desc = $(this).find('desc').text();
var _currency = $(this).find('currency').text();
var _custom1 = $(this).find('custom1').text();
var _price = $(this).find('price').text();
var _deltime = $(this).find('deltime').text();
var _delcost = $(this).find('delcost').text();
var _imgurl = $(this).find('imgurl').text();
var _alternate_image = $(this).find('alternate_image').text();
$("h2._name").eq(i).text(_name);
$(".price").eq(i).text(_price);
var background_url = "url(" + _imgurl + ")";
$(".panel").eq(i).css("background", background_url);
} else {
return false;
}
});
console.log('done reading file');
}
});
有什么方法可以更快地讀取XML文件,從而可以更有效地呈現產品?
PHP具有用於大型XML文件的XMLReader / XMLWriter。 您生成的XML不大(取決於每頁的產品限制)。 因此,您可以使用DOM進行編寫,並且只需要XMLReader。
這是一個簡化XML的示例:
$data = <<<'XML'
<merchant xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0">
<title>End | Globally Sourced Menswear</title>
<product><name>Comme des Garcons Play Full Zip Hoody</name></product>
<product><name>Pharrell: Places & Spaces I've Been - Pink Cover</name></product>
<product><name>The Rig Out Issue 6</name></product>
<product><name>Baxter of California Beard Comb</name></product>
<product><name>Baxter of California Comb</name></product>
</merchant>
XML;
$template = <<<'XML'
<merchant xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0"/>
XML;
$reader = new XMLReader();
$reader->open('data://text/plain;base64,'.base64_encode($data));
// prepare the target document
$document = new DOMDocument();
$document->preserveWhiteSpace = FALSE;
$document->loadXML($template);
// iterate to the first product element
do {
$found = $reader->read();
} while ($found && $reader->localName !== 'product');
$offset = 0;
$limit = 2;
$end = $offset + $limit;
$i = 0;
while ($found && $i < $end) {
if ($offset <= $i) {
// expand the current "product" and append it to the "merchant" node
$document->documentElement->appendChild($reader->expand($document));
}
$i++;
$found = $reader->next('product');
}
$document->formatOutput = TRUE;
echo $document->saveXML();
輸出:
<?xml version="1.0"?>
<merchant xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0">
<product>
<name>Comme des Garcons Play Full Zip Hoody</name>
</product>
<product>
<name>Pharrell: Places & Spaces I've Been - Pink Cover</name>
</product>
</merchant>
使用原始文件上的腳本進行多個偏移量(分頁)的時間會增加,因為XMLReader仍必須在到達偏移量之前遍歷產品節點。 但是,您可以在下載提要的腳本中執行此操作,從而避免了請求中的工作。 這是我的機器上限制20種產品的一些結果:
[Page] => Duration
[1] => 3ms
[51] => 14ms
[101] => 25ms
[151] => 35ms
[201] => 44ms
[251] => 55ms
[301] => 66ms
[351] => 91ms
[401] => 95ms
[451] => 110ms
您還應該考慮將文件(使用XMLReader + DOM)解析到數據庫(SQLite,...)或搜索索引(Elastic Search,...)中。 這將允許您生成過濾結果。
PS: btw您的XML文件看起來壞了。 它將Atom定義為默認名稱空間,使用g
前綴定義的Google名稱空間我看不到任何元素。 我希望merchant
和product
成為該名稱空間的一部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.