Firefox 1.1, E4X, ECMA-357
9th July 2005 - 12:00
var myBooks =
<books>
<book>
<title>Title</title>
<author>Author</author>
<desc>Description</desc>
</book>
</books>;
alert(typeof(myBooks)); // xml
alert(XMLbooks..book[0].title.text()); // Title
Интересно?
- ECMA: «ECMAScript for XML (E4X) Specification»
- Bug 275742 «Enable e4x in JS components»
- Jon Udell: «Introduction to E4X»
- Kurt Cagle: «Objectifying XML — E4X for Firefox 1.1»
- Update. Xpoint.ru: «Работа с ECMAScript for XML (E4X)»
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>e4x :: ECMA-357</title>
<style type="text/css">
<![CDATA[
/* (Высоко)художественное оформление */
html {background:#fff; color:#000;}
table {font:.75em Verdana;}
th, td {
padding: .2em .5em;
border:1px solid #333;
}
]]>
</style>
<script type="application/x-javascript; e4x=1">
<![CDATA[
function e4xTest(){
//~ список книг
var XMLbooks =
<books>
<book id="1" fav="true">
<title>Title 1</title>
<author>Author 1</author>
<desc>Description 1</desc>
<cost m="$">5.45</cost>
<count>6</count>
</book>
<book id="50">
<title>Title 2</title>
<author>Author 2</author>
<desc>Description 3</desc>
<cost m="€">15.40</cost>
<count>4</count>
</book>
<book id="10" fav="true">
<title>Title 3</title>
<author>Author 3</author>
<desc>Description 3</desc>
<cost m="$">9.95</cost>
<count>8</count>
</book>
<book id="99" fav="false">
<title>Title 4</title>
<author>Author 4</author>
<desc>Description 4</desc>
<cost m="$">19.95</cost>
<count>0</count>
</book>
<book id="78">
<title>Title 5</title>
<author>Author 5</author>
<desc>Description 5</desc>
<cost m="$">1.40</cost>
<count>10</count>
</book>
<courseEuro>1.2</courseEuro>
</books>;
//~ ах, да,.. есть ещё одна книга
var oneMoreBook =
<book id="45">
<title>Title 6</title>
<author>Author 6</author>
<desc>Description 6</desc>
<cost m="€">7.35</cost>
<count>1</count>
</book>;
//~ опять забыл: она же любимая!
oneMoreBook.@fav = 'true';
//~ добавляем её к списку
XMLbooks.insertChildAfter(null, oneMoreBook);
//~ хотя нет, пусть будет последней
delete XMLbooks.book[0];
XMLbooks.insertChildAfter(
XMLbooks.book[XMLbooks.book.length()-1],
oneMoreBook);
//~ столики (для табличных данных, ебстественно)
var table1 =
<table>
<tr>
<th>№</th>
<th>Title</th>
<th>Description</th>
<th>Cost</th>
<th>Count</th>
<th>Item Total</th>
<th>Running Total</th>
</tr>
<tr>
<th>$</th>
<th>€</th>
</tr>
</table>;
//~ стоп, стоп, стоп... что-то не сходится...
//~ не беда, сейчас поправим
for (item in ths = table1.tr[0].th)
ths[item].@rowspan = 2;
ths[item].@rowspan = false;
ths[item].@colspan = 2;
//~ баловство
for (item in ths = table1..tr.th)
ths[item].@style = "border:2px solid #333";
var table2 =
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Description</th>
<th>Price</th>
</tr>
</table>;
//~ для представления цен с n нулями после запятой
Number.prototype.fix = function(n) {
return this.toFixed(n);
}
String.prototype.fix = function(n) {
return new Number(this).toFixed(n);
}
//~ список всех книг
var books = XMLbooks..book;
//~ их общая стоимость
var totalPrice = 0;
//~ только книг, продающихся за доллары
var totalPriceUSD = 0;
//~ только книг, продающихся за евро
var totalPriceEURO = 0;
for (var i=0; i<books.length(); i++) {
//~ цепляем книгу
var book = books[i];
//~ считаем цену = кол-во экземпляров * цена книги
price = book.count * book.cost;
//~ увеличиваем общую стоимость
book.cost.@m == '$' ? totalPriceUSD += price :
totalPriceEURO += price;
//~ новая строка в таблице
table1.appendChild(
<tr>
<td>{i+1}</td>
<td>{book.title.text()}</td>
<td>{book.desc.text()}</td>
<td>{book.cost.@m} {book.cost.fix(2)}</td>
<td style="text-align:center">{book.count}</td>
<td>{book.cost.@m} {price.fix(2)}</td>
<td>{totalPriceUSD.fix(2)}</td>
<td>{totalPriceEURO.fix(2)}</td>
</tr>);
}
totalPrice = totalPriceUSD + totalPriceEURO * XMLbooks.courseEuro[0];
table1.appendChild(
<tr>
<td colspan="6">Summ (USD + EURO*{XMLbooks.courseEuro[0]})</td>
<td colspan="2" style="text-align:center">$ {totalPrice.fix(2)}</td>
</tr>);
var show = document.getElementsByTagName('body')[0];
show.innerHTML += '<h2>All books (' +
books.length() + ')</h2>';
show.innerHTML += table1;
//~ ещё раз, но только любимые книги
var favbooks = XMLbooks..book.(@fav == 'true');
for (item in favbooks) {
var favbook = favbooks[item];
table2.appendChild(
<tr>
<td>{favbook.title.text()}</td>
<td>{favbook.author.text()}</td>
<td>{favbook.desc.text()}</td>
<td>{no matter}</td>
</tr>);
}
show.innerHTML += '<h2>Favourite books (' +
favbooks.length() + ')</h2>';
show.innerHTML += table2;
}//~ e4xTest() end
//~ мотор!
window.onload = e4xTest;
]]>
</script>
</head>
<body/>
</html>
Categories: dHtml | comments: (5)
Комментарии
1. Lynn 12th July 2005 - 03:14
£ != euro
Mash:
€, ага. Ну, хоть кому-то интересно. :)
2. Lynn 12th July 2005 - 03:15
Ой, а что-то наверху какая-то фигня запостилась?
В общем фунты стерлингов это не евро :)
Mash:
Фигню поправил. :)
3. qborrd 14th July 2005 - 23:59
Отличная штука… прочитал все поясняющие ссылки, вопрос возник такой, можно ли сделать так, чтобы данные брались из внешнего источника — текстового файла с соответствующей разметкой, а шаблоны поиска и заполнения находились в исходной странице, которую загружает пользователь?
Я просто как-то смысла не вижу тогда в данном примере… не легче сделать экспорт из электронных таблиц? Только не бейте, если чего… :)
Mash:
Динамическое создание различных <script> или AJAX.
+: если страница представляет собой не суповой набор тэгов, а нормальный XHTML, то можно подумать и в направлении манипулирования содержимым этой страницы.
4. qborrd 15th July 2005 - 00:45
читая твои артикли понимаешь, что ты стал самым настоящим корейцем, всмысле съел сабаку на этом, в конструктивно выражаясь :)
5. Владимир Палант 17th September 2005 - 03:36
Там ещё одна маленькая да удаленькая фича появилась. Последний цикл можно записать и так:
for each (var favbook in favbooks) {
…
}
Mash:
Сейчас посмотрел в 20050711 — это даже в июле работало. Хорошая штука, упустил. :)