Здравствуйте!
Пишу функции для справочника в формате chm. Задача - локально подключить и отпарсить xml файл объёмом 17-25 мб (следовательно выполнить это на движке IE6). В результате получил огромную нагрузку на процессор (если решитесь запустить index.html на слабом компе, то запаситесь терпением на время обработки. Chm работает быстрее и выведет данные, примерно, через 5-10 сек).
Помогите найти более логичное и быстрее работающее решение задачи чем то, что я своял:
Теперь всё по порядку.
xml имеет следующую структуру:
Код:
|
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Row>
<Col>text</Col>
<Col>text</Col>
...
<Col>img/name1.jpg</Col>
<Col>img/name2.jpg</Col>
</Row>
...
<Row>
<Col>text</Col>
<Col>text</Col>
<Col>-</Col>
...
<Col>img/name.jpg</Col>
<Col>img/name.jpg</Col>
</Row>
</Root> |
*! Опытным путем выяснил, что документ с пустыми тегами типа <Col></Col> не проходит обработку, функция стопарится на firstChild.data, пришлось заменять пустые элементы на <Col>-</Col>.
С подключением xml я справился следующим образом (эксперимента ради реализовал поддержку и для Firefox с помощью объекта XMLHttpRequest):
//см. рекомендации на
w3schools.com
// 1. делаем запрос к БД, т.е. загружаем xml
function createDocument()
{
//Temporary DOM object.
var xmlDoc;
//Create the DOM object for IE
if (window.ActiveXObject)
{
var versions =
[
"Msxml2.DOMDocument.6.0",
"Msxml2.DOMDocument.3.0"
];
for (var i = 0; i < versions.length; i++)
{
try
{
xmlDoc = new ActiveXObject(versions[i]);
xmlDoc.load("data_01.xml");
return xmlDoc;
}
catch (error)
{
//do nothing here
}
}
}
//Cтроим DOM для Firefox
else if (window.XMLHttpRequest)
{// локально работае везде кроме Chrome и Opera 11
xmlDoc=new XMLHttpRequest();
xmlDoc.open("GET","data_01.xml",false);
xmlDoc.send();
xmlDoc=xmlDoc.responseXML;
return xmlDoc;
}
return null;
}
Далее, парсим xml в двухмерный массив arr[i][j]
var xmlDoc = createDocument();
// 2. парсим тело полученного документа в массив извлекая текстовые данные посредством свойств firstChild.data
var arr = [],
xmlRows = xmlDoc.getElementsByTagName('Row');
// log
log("Загружено элементов Row: "+xmlRows.length+". ");
for(var i=0; i<xmlRows.length; i++) {
var xmlCols = xmlRows[i].getElementsByTagName('Col');
arr[i] = [];
for(var j=0; j<xmlCols.length; j++) {
arr[i][j] = xmlCols[j].firstChild.data;
// log
// log("Загружено элементов Col: "+arr[i][j].length+". ");
}
}
// Возвращаем массив Arr
return arr;
Потом вывожу данные построчно в динамически формируемый список.
На этом, пока, всё.
В дальнейшем предполагается разбить полученный массив arr на множество двухмерных массивов, данные которых будут выводиться на экран в зависимости от действий пользователей.
Вот весь рабочий код:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Chm справочник на xml базе данных</title>
<body>
<div id="logDiv" style="position: relative; clear:both; margin: 0px auto; width: 334px; height: 100px; overflow: auto; white-space: pre-wrap; border: 1px solid black; left: 9px; margin-top: 0px;"></div>
<center><input type="button" value="Очистить журнал" onclick="clearLog();"/></center>
<script type="text/javascript">
function log(str) {
document.getElementById("logDiv").innerHTML += str+"\n";
}
function clearLog() {
document.getElementById("logDiv").innerHTML = "";
}
// Чтобы не засорять пространство глобальных переменных все делаем в безымянной функции
var DBArray = (function() {
// 1. делаем запрос к БД, т.е. загружаем xml
function createDocument()
{
//Temporary DOM object.
var xmlDoc;
//Create the DOM object for IE
if (window.ActiveXObject)
{
var versions =
[
"Msxml2.DOMDocument.6.0",
"Msxml2.DOMDocument.3.0"
];
for (var i = 0; i < versions.length; i++)
{
try
{
xmlDoc = new ActiveXObject(versions[i]);
xmlDoc.load("data_01.xml");
return xmlDoc;
}
catch (error)
{
//do nothing here
}
}
}
//Cтроим DOM для Firefox
else if (window.XMLHttpRequest)
{// локально работае везде кроме Chrome и Opera 11
xmlDoc=new XMLHttpRequest();
xmlDoc.open("GET","data_01.xml",false);
xmlDoc.send();
xmlDoc=xmlDoc.responseXML;
return xmlDoc;
}
return null;
}
var xmlDoc = createDocument();
// 2. парсим тело полученного документа в массив
var arr = [],
xmlRows = xmlDoc.getElementsByTagName('Row');
// log
log("Загружено элементов Row: "+xmlRows.length+". ");
for(var i=0; i<xmlRows.length; i++) {
var xmlCols = xmlRows[i].getElementsByTagName('Col');
arr[i] = [];
for(var j=0; j<xmlCols.length; j++) {
arr[i][j] = xmlCols[j].firstChild.data;
// log
// log("Загружено элементов Col: "+arr[i][j].length+". ");
}
}
// Возвращаем массив Arr
return arr;
})();
// выводим списком текстовое содержимое элементов Col которое отпарcили в массив arr функции DBArray
function createList(data) {
var list = document.createElement("ul");
for (var i = 0; i < data.length; i++) {
var newItem = document.createElement("li");
var newText = document.createTextNode(data[i]);
newItem.appendChild(newText);
list.appendChild(newItem);
}
return list;
}
window.onload = function() {
var list = createList(DBArray);
document.body.appendChild(list);
}
</script>
</body>
</html>
P. S. К сожалению я специализируюсь, в основном, на верстке и пока плохо владею javascript. Прошу простить если моя задача покажется Вам слишком абсурдной, с радостью приму любые советы по решению изложенной проблемы.