Intereting Posts
Получение: допустимый объем памяти 33554432 байт исчерпан Функция почты PHP не может отправлять электронную почту, когда я добавил .com.sg, а не только .com Можем ли мы использовать сеанс для создания глобальной переменной для всего клиента? Динамический родственный выбор с помощью jQuery, не работает в IE открытый аккордеон с внешней связью WordPress Admin – требуется обычная мета-проверка PHP include_once: обработка импорта, т.е. для файлов конфигурации Использование метода number_format в Laravel Как использовать InputFilterManager для создания пользовательских InputFilters в Zf2 как изменить ключ в массиве при сохранении порядка? Вставка записей в базу данных mysql с использованием php с использованием Ajax шифрование пароля с использованием php Вставка данных в таблицу (вставка mysqli) Печатать файл в PHP 5.6 (все еще) невозможно? Как я могу циклически перебирать шестнадцатеричные цветовые коды в PHP?

XSLT: использовать параметры в xls: сортировать атрибуты (динамическая сортировка)

Как применить параметр к атрибуту select и order в элементе xsl:sort ? Мне хотелось бы сделать эту динамику с PHP с чем-то вроде этого:

 $xsl = new XSLTProcessor(); $xslDoc = new DOMDocument(); $xslDoc->load( $this->_xslFilePath ); $xsl->importStyleSheet( $xslDoc ); $xsl->setParameter( '', 'sortBy', 'viewCount' ); $xsl->setParameter( '', 'order', 'descending' ); 

Но я сначала должен был понять, как заставить это работать. Я пробовал следующее, но он дает мне ошибку компиляции: «Недопустимое значение $ order for order». $sortBy ничего не делает:

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:param name="sortBy" select="viewCount"/> <xsl:param name="order" select="descending"/> <xsl:template match="/"> <media> <xsl:for-each select="media/medium"> <xsl:sort select="$sortBy" order="$order"/> // <someoutput> </xsl:for-each> </media> </xsl:template> </xsl:stylesheet> 

Вы близки к правильному решению , но есть несколько вопросов:

  1. <xsl:param name="sortBy" select="viewCount"/> Это определяет параметр $sortBy как значение viewCount текущего узла (узла документа). Поскольку верхний элемент не называется viewCount , параметр $sortBy определенный таким образом, вообще не имеет значения.

  2. <xsl:param name="order" select="descending"/> То же.

  3. <xsl:sort select="$sortBy" order="$order"/> Даже если исправлены проблемы 1 и 2., эта инструкция xslt все еще проблематична. Он определяет значение атрибута order как буквенную строку '$order' – не как значение параметра $order . Способ сделать это в XSLT – это использовать AVT (шаблон значения атрибута). Всякий раз, когда мы хотим указать, что внутри значения атрибута мы хотим, чтобы определенная строка была оценена как выражение XPath, эта строка должна быть окружена фигурными фигурными скобками.

Таким образом, атрибут order должен быть указан как: order = '{$order}' .

К сожалению, AVT не могут использоваться для атрибута select (другое правило из спецификации XSLT).

Способ задания значения атрибута select является немного более сложным:

select='*[name()=$sortBy]' Это говорит: сортировка по дочернему элементу, имя которого совпадает с значением переменной $sortBy .

Чтобы соединить все это, вот скорректированное преобразование :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="sortBy" select="'viewCount'"/> <xsl:param name="order" select="'descending'"/> <xsl:template match="/"> <media> <xsl:for-each select="media/medium"> <xsl:sort select="*[name()=$sortBy]" order="{$order}"/> <xsl:copy-of select="."/> </xsl:for-each> </media> </xsl:template> </xsl:stylesheet> 

Когда это преобразование применяется к следующему XML-документу :

 <media> <medium> <viewCount>2</viewCount> </medium> <medium> <viewCount>1</viewCount> </medium> <medium> <viewCount>5</viewCount> </medium> </media> 

Производится правильный результат :

 <media> <medium> <viewCount>5</viewCount> </medium> <medium> <viewCount>2</viewCount> </medium> <medium> <viewCount>1</viewCount> </medium> </media>