XSLT - Стивен Холзнер
Шрифт:
Интервал:
Закладка:
</TR>
<xsl:apply-templates select="/PLANETS/PLANET">
<xsl:sort select="NAME" order="ascending"/>
</xsl:apply-templates>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="PLANET">
<TR>
<TD><xsl:value-of select="NAME"/></TD>
<TD><xsl:value-of select="MASS"/></TD>
<TD><xsl:value-of select="RADIUS"/></TD>
<TD><xsl:value-of select="DAY"/></TD>
</TR>
</xsl:template>
</xsl:stylesheet>
Эта таблица стилей сортирует планеты в алфавитном порядке по их названиям; но есть и другие возможности: можно позволить пользователю осуществлять сортировку и по другому критерию. Для этого выберите в данной таблице стилей атрибут select элемента <xsl:sort> и при помощи JavaScript измените его динамически с «NAME» на «MASS», «RADIUS» или на другой критерий по желанию пользователя, и затем снова выполните преобразование XSLT. При повторном осуществлении преобразования появится новая таблица с новым порядком сортировки.
В качестве первого шага в создании нужной нам HTML-страницы я загружу planets.xml и требуемую таблицу стилей и выполню сортировку по умолчанию, то есть по названию планет:
<HTML>
<HEAD>
<TITLE>
Applying Dynamic Styles
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var XMLDocument;
var XSLDocument;
var HTMLtarget;
function initialize() {
XMLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');
XSLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');
HTMLtarget = document.all['targetDIV'];
XMLDocument.validateOnParse = true;
XMLDocument.load('planets.xml');
if (XMLDocument.parseError.errorCode != 0) {
HTMLtarget.innerHTML = "Error!";
return false;
}
XSLDocument.validateOnParse = true;
XSLDocument.load('planets.xsl');
if (XSLDocument.parseError.errorCode != 0) {
HTMLtarget.innerHTML = "Error!";
return false;
}
HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);
}
.
.
.
Эту часть вы уже видели раньше. Но пользователь теперь может отсортировать таблицу щелчком мыши по массе, радиусу и т.д. Для новой сортировки таблицы я написал функцию sort — ей при щелчке на кнопке передается имя узла (например, «MASS»), по которому нужно провести сортировку. Вот как создаются различные кнопки, показанные на рис. 10.3:
<INPUT ТУРЕ="BUTTON" ONCLICK="sort('NAME')" VALUE="Sort by name"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('MASS')" VALUE="Sort by mass"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('RADIUS')" VALUE="Sort by radius"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('DAY')" VALUE="Sort by day"></INPUT>
Затем в функции sort я хочу выполнить новую сортировку по имени переданного узла. Для этого я изменяю атрибут select элемента <xsl:sort> на имя нового узла, по которому нужно сортировать. Вот как теперь выглядит атрибут select.
<xsl:apply-templates select="/PLANETS/PLANET">
<xsl:sort select="NAME" order="ascending"/>
</xsl:apply-templates>
Я могу обратиться к этому узлу из таблицы стилей, теперь хранимой в объекте XSLDocument, передав в метод selectSingleNode упомянутого объекта выражение XPath. Метод selectSingleNode возвращает объект node, и можно изменить текстовое значение узла при помощи свойства nodeValue объекта node. В таком случае я только устанавливаю атрибут select в имя нового узла, по которому будет вестись сортировка:
<HTML>
<HEAD>
<TITLE>
Applying Dynamic Styles
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function initialize() {
.
.
.
}
function sort(sortNode) {
(XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue
= sortNode;
.
.
.
}
</SCRIPT>
.
.
Теперь все, что осталось сделать, — снова выполнить преобразование и вывести результаты:
<HTML>
<HEAD>
<TITLE>
Applying Dynamic Styles
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function initialize() {
.
.
.
}
function sort(sortNode) {
(XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue
= sortNode;
HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);
}
</SCRIPT>
</HEAD>
.
.
.
Операция завершена. Результаты показаны на рис. 10.3. При щелчке на кнопке таблица сортируется заново по выбранному значению узла (имейте в виду, что сортировка ведется по алфавиту; сортировка по числовым значениям обсуждается в главе 5, где описывается элемент <xsl:sort>) и отображается еще раз с новым порядком сортировки. Вот вся HTML-страница (листинг 10.3).
Листинг 10.3. Применение динамических XSLT-преобразований<HTML>
<HEAD>
<TITLE>
Applying Dynamic Styles
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
var XMLDocument;
var XSLDocument;
var HTMLtarget;
function initialize() {
XMLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');
XSLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');
HTMLtarget = document.all['targetDIV'];
XMLDocument.validateOnParse = true;
XMLDocument.load('planets.xml');
if (XMLDocument.parseError.errorCode != 0) {
HTMLtarget.innerHTML = "Error!";
return false;
}
XSLDocument.validateOnParse = true;
XSLDocument load('planets.xsl');
if (XSLDocument.parseError.errorCode != 0) {
HTMLtarget.innerHTML = "Error!";
return false;
}
HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);
}
function sort(sortNode) {
(XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue
= sortNode;
HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);
}
</SCRIPT>
</HEAD>
<BODY ONLOAD="initialize()">
<CENTER>
<DIV ID="targetDIV"></DIV>
<BR>
<BR>
<INPUT TYPE="BUTTON" ONCLICK="sort('NAME')" VALUE="Sort by name"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('MASS')" VALUE="Sort by mass"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('RADIUS')" VALUE="Sort by radius"></INPUT>
<INPUT TYPE="BUTTON" ONCLICK="sort('DAY')" VALUE="Sort by day"></INPUT>
</CENTER>
</BODY>
</HTML>
На самом деле загрузить документы XML и XSL в Internet Explorer можно несколькими способами. Для создания объектов XMLDocument и XSLDocument я использовал класс ActiveXObject, но эти объекты можно создавать и непосредственно обращаясь к содержащим документы XML объектам ActiveX по идентификатору класса, хранимому в реестре Windows. В следующем примере я таким образом загружу planets.xml и planets.xsl в XMLDocument и XSLDocument:
XMLDocument = document.all['XMLdoc'];
XSLDocument = document.all['XSLdoc'];
XMLDocument.load('planets.xml');
XSLDocument.load(' planets.xsl');
.
.
.
<OBJECT ID="XMLdoc" WIDTH="0" HEIGHT="0"
CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">
</OBJECT>
<OBJECT ID="XSLdoc" WIDTH="0" HEIGHT="0"
CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">
</OBJECT>
Эта техника не так надежна, как использование класса ActiveXObject, поскольку идентификаторы классов могут различаться в разных версиях Internet Explorer. (Приведены идентификаторы классов для Internet Explorer 5.5). Но есть еще один способ загрузить документы XML и XSL в Internet Explorer — при помощи участков (island) XML.
Internet Explorer и участки данных XML
В Internet Explorer есть специальный тег <XML>, при помощи которого можно создавать участки (island) XML. Участок XML может содержать либо сам код XML, либо ссылку на XML-документ.
Участки XML упрощают загрузку документов XML и XSL, поэтому их стоит здесь рассмотреть. В следующем примере я создаю два участка XML, sourceDocument и stylesheet, и загружаю planets.xml и planets.xsl, просто обратившись к ним через атрибут src:
<HTML>
<HEAD>
<TITLE>
The Planets Table
</TITLE>
<XML id="sourceDocument" src="planets.xml"></XML>