Вызовите шаблон XSLT и сохраните все выходные данные в переменной


Я хочу вызвать и шаблон и сохранить выходные данные в переменной. Я хочу сохранить все вывода, включая разметку HTML, но это не то, что происходит.

Например, возьмем такой простой XSLT:

<xsl:call-template name="demonstration">

<xsl:template name="demonstration">
    <p>Just a test</p>
</xsl:template>

Этот простой шаблон выведет <p>Just a test</p> на HTML-страницу. Если я просматриваю источник страницы, я вижу это (конечно). Теперь возьмем этот пример, используя тот же шаблон, но вместо того, чтобы просто выводить в HTML, я хочу сохранить вывод в a переменная:

<xsl:variable name="test">
    <xsl:call-template name="demonstration">
</xsl:variable>
<xsl:value-of select="$test"/>


<xsl:template name="demonstration">
    <p>Just a test</p>
</xsl:template>

Просмотр переменной показывает, что теперь единственным выходом является Just a test.

Куда делась разметка HTML? Я хотел бы сохранить выходные данные шаблона вызова в переменной, но мне также нужна разметка HTML.

Есть ли способ избежать потери HTML-тегов при вызове шаблона, подобного этому? Есть ли другой способ написания моего шаблона? Может быть, мне не хватает декорации? Я пробовал disable-escape-encoding, но это не имеет значения (в Safari at наименьший).

Я предпочитаю использовать шаблон для обеих целей: я хотел бы иметь возможность просто вызвать его и иметь вывод в HTML-странице для просмотра. Я также хотел бы иметь возможность обернуть вызов в переменную, но важно, чтобы оба метода вызова включали все HTML-теги / разметку, как указано в шаблоне.

Редактировать:

Я уже пробовал оба опубликованных ответа, но copy-of дает мне тот же результат, что и value-of. На самом деле, я не использую value-of, я только показывает, как дублировать проблему. Вот более подробное объяснение того, что я пытаюсь сделать.

Есть таблица стилей, которая используется для преобразования довольно большого XML, полученного из ответа REST. Таблица стилей имеет свой метод вывода, установленный для html.

Один из шаблонов в этой таблице стилей делает много решений о том, как отображать до 4 строк данных в таблице. Есть 2 столбца, один для метки, другой для данных.

Принятие решений то, что сделано, включает в себя то, что текст метки и какой класс - иногда метка зеленая, иногда красная и т. д. Столбец данных может содержать текст и / или цифры. Часть текста может быть выделена жирным шрифтом, часть-цветным. Существует множество предпосылок, которые определяют эти атрибуты.

Если бы я отображал детали одного элемента, я бы закончил с этим шаблоном, но один из этих элементов может иметь множество выбранных атрибутов. Например, может быть размер и цвет. В зависимости от того, какой размер или цвет выбирает пользователь, цена может быть разной, конкретный товар может отсутствовать на складе, если он имеет другую цену, то он будет иметь другую экономию для пользователя. Различные товары могут иметь бесплатную доставку или могут быть доступны только для предварительного заказа. Есть много атрибутов.

И поэтому у меня есть шаблон, который анализует все эти предпосылки и строит <tr><td></td><td></td></tr>, заполненный очень простым текстом и данными, полученными некоторыми не очень простыми логика.

Я модулировал этот шаблон так, чтобы я мог вызвать его для любого из элементов. Он парамертизирован, поэтому я могу указать текст метки, данные, класс и несколько других вещей.

При загрузке веб-страницы отображается стандартный / основной элемент вместе с общей информацией - например, диапазон цен и диапазон экономии и т. д.

Но когда пользователь выбирает цвет или размер, эти строки таблицы должны быть обновлены с правильными данными. Я уже обработал данные из XML и было бы очень дорого сделать еще один запрос сервера, поэтому я создал массив строк JSON, содержащий все данные для всех различных типов элементов. Я сохраняю этот JSON в атрибуте value скрытого входного элемента управления. Есть и другие способы сделать это, да, но это работает и кажется мне управляемым.

Поскольку логика для создания этих строк таблицы находится в таблице стилей на сервере, я выполняю всю эту логику для всех элементов, а затем передаю вычисленные строки для клиента. Вот пример того, как это выглядит:

<input id="hfData" type="hidden" value="[
{"ProductID": "00001", "Color": "Beige", "Size": "14"},
{"ProductID": "00002", "Color": "Black", "Size": "14"},
{"ProductID": "00003", "Color": "Blue", "Size": "10"},
{"ProductID": "00004", "Color": "Pink", "Size": "10"},
{"ProductID": "00005", "Color": "Yellow", "Size": "10"}
]"
/>

Затем у меня есть небольшой скрипт JQuery, который запускается каждый раз, когда пользователь изменяет выбор выпадающего списка или изменяет атрибут. Сценарий анализирует вышеупомянутый JSON и определяет, что такое текущий настроенный ProductID.

Примечание: поскольку атрибут value входного элемента управления не был бы действителен, если бы я имел двойные кавычки, разбросанные по нему, как это, они фактически все &quot;. Я показываю двойную игру. цитаты здесь, чтобы было легко смотреть.

Как только ProductID определен, страница обновляется множеством различных деталей, как описано ранее в этом редактировании. Эти сведения получены из еще одного объекта JSON, который я создал-опять же, поскольку все сведения о продукте известны в таблице стилей XSLT, именно там я создаю массив строк JSON.

<input id="hfDetails" type="hidden" value="[
{"ProductID": "00001", "ListPrice": "<tr class="collapsed"><td class="datalabel">List Price:</td><td class="datainfo"></td></tr>", "YourPrice": "<tr><td class="datalabel">Price:</td><td class="datainfo">$23.99 & is elegible for <span class="freeshipping">FREE</span> shipping <a href="#">Details</a></td></tr>"},

... etc, etc, etc ...

]"
/>

Как вы можете видеть, скрытый вход чуть выше имеет атрибут value, содержащий объект JSON, который содержит HTML разметка. Я видел эту работу, но для того, чтобы заставить JSON работать правильно, мне нужно избежать всех тегов. Амперсанды должны быть &amp;, тогда есть &lt;, &gt; а также экранирование всех цитат с обратной косой чертой. Я закодировал все это таким образом, и это работает - хотя и неприятно на вид, это работает, и это предотвращает меня от необходимости совершать круговые поездки к серверу - это мешает мне поместить всю логику для создания этих строк на стороне клиента.

Все это не имеет никакого отношения к проблема у меня есть, но я надеюсь избавиться от всех комментариев от профессоров JSON и XSL/XML, которые бросают мне вызов за то, что JSON и XSLT (или HTML) в одном предложении...

Теперь, я надеюсь, что смогу показать (очень просто) точную проблему, с которой я сталкиваюсь. Для начала, это действительно имеет очень мало общего с JSON. Это практически не имеет ничего общего с использованием xsl:value-of над xsl:copy-of.

Здесь я создаю скрытое поле ввода с атрибутом value, содержащим JSON строка:

<input>
  <xsl:attribute name="id">
    <xsl:value-of select="$id"/>
  </xsl:attribute>
  <xsl:attribute name="type">
    <xsl:text>hidden</xsl:text>
  </xsl:attribute>
  <xsl:attribute name="runat">
    <xsl:text>server</xsl:text>
  </xsl:attribute>
  <xsl:attribute name="value">
    <xsl:text>[</xsl:text>

    <xsl:for-each select="Items/Item">
          <xsl:call-template name="JSONItemDetails">
            <xsl:with-param name="offerNode" select="Offers"/>
            <xsl:with-param name="lastitem" select="position() = last()"/>
          </xsl:call-template>
    </xsl:for-each>

    <xsl:text>]</xsl:text>
  </xsl:attribute>
</input>


<xsl:template name="JSONItemDetails">
    <xsl:param name="offerNode" select="."/>
    <xsl:param name="attributesNode" select="ItemAttributes"/>
    <xsl:param name="listprice" select="0"/>
    <xsl:param name="lastitem" select="false()"/>

    <!-- Product ID -->
    <xsl:text>{</xsl:text>
    <xsl:text>&quot;ProductID&quot;: </xsl:text>
    <xsl:text>&quot;</xsl:text>
    <xsl:value-of select="./ProductID"/>
    <xsl:text>&quot;,</xsl:text>

    <xsl:for-each select="msxml:node-set($offerNode)">

        <!-- Title -->
        <xsl:text>&quot;Title&quot;: </xsl:text>
        <xsl:text>&quot;</xsl:text>
        <xsl:call-template name="escapeQuote">
            <xsl:with-param name="pText">
            <xsl:call-template name="title">
                <xsl:with-param name="node" select="$attributesNode" />
            </xsl:call-template>
            </xsl:with-param>
        </xsl:call-template>
        <xsl:text>&quot;,</xsl:text>

        <!-- List Price -->
        <xsl:text>&quot;ListPrice&quot;: </xsl:text>
        <xsl:text>&quot;</xsl:text>
        <xsl:call-template name="escapeQuote">
            <xsl:with-param name="pText">
            <xsl:call-template name="DataTableRow">
                <xsl:with-param name="label" select="'List Price:'" />
                <xsl:with-param name="data" select="./Price/FormattedPrice" />
                <xsl:with-param name="dataid" select="'listprice'" />
            </xsl:call-template>
            </xsl:with-param>
        </xsl:call-template>
        <xsl:text>&quot;</xsl:text>

    </xsl:for-each>

    <xsl:text>}</xsl:text>
    <xsl:if test="$lastitem != true()">
        <xsl:text>,</xsl:text>
    </xsl:if>

Шаблон DataTableRow делает много вещей, которые в основном обеспечивают согласованность, но также очищают все случайные HTML-теги, используемые для создания строк и столбцов. Вот этот шаблон.
<xsl:template name="DataTableRow">
    <xsl:param name="label" select="''"/>
    <xsl:param name="data" select="''"/>
    <xsl:param name="dataid" select="''"/>
    <xsl:param name="concat" select="''"/>
    <xsl:param name="class" select="''"/>

    <tr>
        <xsl:choose>
        <xsl:when test="$data = not(string(.))">
          <xsl:attribute name="style">
            <xsl:text>display:none</xsl:text>
          </xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
           <xsl:attribute name="style">
           <xsl:text>display:block</xsl:text>
        </xsl:attribute>
        </xsl:otherwise>
        </xsl:choose>

        <!-- Label Column -->
        <td>
            <div>
                <xsl:choose>
                <xsl:when test="$class = 'bigmaroon'">
                    <xsl:attribute name="class">
                        <xsl:text>datalabel maroon</xsl:text>
                    </xsl:attribute>
               </xsl:when>
               <xsl:otherwise>
                    <xsl:attribute name="class">
                       <xsl:text>datalabel</xsl:text>
                    </xsl:attribute>
               </xsl:otherwise>
               </xsl:choose>
               <xsl:value-of select="$label"/>
           </div>
        </td>

        <!-- Data Column -->
        <td class="datainfo">
            <xsl:attribute name="id">
                <xsl:value-of select="$dataid"/>
            </xsl:attribute>

            <xsl:choose>
            <xsl:when test="$class = 'strike'">
                <strike>
                    <xsl:value-of select="$data" />
                </strike>
                <xsl:value-of select="$concat"/>
            </xsl:when>
            <xsl:when test="$class = 'maroon'">
                <span class="maroon">
                    <xsl:value-of select="$data" />
                </span>
                <xsl:value-of select="$concat"/>
            </xsl:when>
            <xsl:when test="$class = 'bigmaroon'">
                <span class="bigmaroon">
                    <xsl:value-of select="$data" />
                </span>
                <xsl:value-of select="$concat"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$data" />
                <xsl:value-of select="$concat" />
            </xsl:otherwise>
            </xsl:choose>
        </td>
    </tr>

Шаблон DataTableRow имеет немного логики, что было бы грязно делать каждый раз, когда мне нужно было написать одну из этих строк. Во-первых, все эти строки должны существовать в HTML. Если данных нет, то они задаются в стиле display:none. Это важно, так как я не смогу заполнить их данными из моего сценария JQuery, если нет допустимого селектора...

Проблема в том, что после всего этого DataTableRow работает просто отлично, когда он вызывается непосредственно так:

<xsl:call-template name="DataTableRow"/>

В приведенном выше вызове все HTML-теги выводятся на мою веб-страницу. Они прекрасно выглядят, их классы и стили правильные. Я могу назвать его так из любого места в моем шаблоне, и он работает просто отлично. Я уверен, что здесь или там есть ошибка, и я возможно, вы увидите свет на лучший / более эффективный способ кодирования этого, но он в основном работает и хорошо работает для HTML.

Проблема: я не могу получить ни один из тегов HTML, когда я строю свои скрытые поля ввода выше. Единственное значение, которое сохраняется в мои строки JSON несколько свойств innerHTML. DataTableRow вызывается из шаблона JSONItemDetails и вместо того, чтобы получить результат:

<tr><td>Some Label</td><td>Some Data</td></tr>

Я получаю результат

Some LabelSome Data

Это было ужасно много информации, чтобы задать такой вопрос. простой вопрос, но я получаю ответы, которые, кажется, намекают, что я не делаю все правильно, если я имею дело с JSON в XSLT/HTML.

Может ли кто - нибудь помочь с моей проблемой? Почему HTML-теги удаляются из вывода DataTableRow, когда я вызываю его в JSONItemDetails для создания моей строки JSON?

Править #2:

У меня есть несколько вещей, происходящих с моим кодом, которые вызывают эту проблему удаления HTML-тегов. Я наконец-то получаю ручку о том, что вызвало проблему, и теперь я пытаюсь выяснить, как решить эту проблему. Вот дополнительные примечания.

Я могу подтвердить, xsl:value-of удаляет мои HTML-теги из вывода вызова шаблона. xsl:copy-of показывает мне теги, которые я ожидаю. Это большая помощь для меня в понимании того, где находится проблема, но это также позволяет мне идентифицировать другие проблемы.

  1. xsl-copy не может использоваться для вывода под атрибутом value= тега. Хотя я понимаю, почему. Я не знаю, как справиться с этой проблемой, если я продолжу двигаться в том направлении, в котором я шел.
  2. даже если я найду решение #1, я должен выяснить, как избежать двойных кавычек в моей HTML-разметке. Т. е.: двойная кавычка недопустима в атрибуте value=. Я понимаю, что Апостроф будет работать, но эти двойные кавычки создаются из использования xsl:attribute под определенными тегами для указания класса или окказионального стиля. У меня есть шаблон, который экранирует двойные кавычки с обратной косой чертой, но вызов его также удаляет мои HTML-теги, и я не вижу, почему - поэтому я не знаю, как это исправить. Я опубликую код для этого шаблона ниже.

Если бы у меня был обходной путь для вышеупомянутых 2 проблем, я мог бы продолжить в том же направлении, но я открыт для советов о том, почему я не должен смешивать данные с дисплеем в моем JSON.

Я смешиваю их, потому что мне не нравится идея поместить логику отображения в мой сценарий JQuery. Я бы хотел, чтобы мой сценарий оставался в неведении об этом. логика. В JQuery просто использовать эти объекты JSON для детализации до ProductID и замены строки таблицы следующим образом:

        var details = $.parseJSON($("#[id*='hfDetails']").val());

        var filteredDetails = $.grep(details, function (n) {
            return n.ProductID == ProductID;
        });

        if (filteredDetails.length > 0) {
            var product = filteredDetails[0];

            $("div#title").html(product.Title);

            $("td#listprice").parent().html(product.ListPrice);
            $("td#price").parent().html(product.Price);
            $("td#yousave").parent().html(product.YouSave);
        }

Если я удалю отображение из моих строк JSON, как советует Дмитрий, мне вдруг придется вложить много логики в мой сценарий jquery, чтобы не только обеспечить <tr> и <td> форматирование (классы), но и логику для обертывания фактических данных, например <strike, <strong>, цветовые характеристики и размеры шрифта или даже является ли конкретная строка таблицы display:block или display:none. Я абсолютно не хочу кодировать какую-либо из этих логик в скрипте JQuery на клиенте.

В моем шаблоне XSLT очень просто создать эти строки на сервере и поместить результаты в мой объект JSON, чтобы я мог использовать приведенный выше скрипт. Надо признать, что это уродливые данные.

Еще одно замечание, независимо от того, отделяю ли я отображение от данных или нет, текущий шаблон XSLT, который я использую для обработки моего XML, все равно будет необходим в том случае, если есть только один элемент с одним возможность отображения. В случае, если есть только один продукт, JSON не появляется на картинке, так как на странице нет элементов управления, чтобы изменить атрибуты продукта (цвет, размер и т. д.).

Я определенно хочу закодировать это "право", поэтому я, безусловно, ценю слышать из опыта. Я просто не думаю, что кто-то может эффективно советовать мне за или против конечного результата, не зная всех сделанных соображений, которые привели меня туда

Вот (было) то шаблон, который я использовал, чтобы избежать двойных кавычек:

<!--
Escape quotes with  for JSON strings
-->
<xsl:template name="escapeQuote">
  <xsl:param name="pText" select="."/>

  <xsl:if test="string-length($pText) >0">
    <xsl:copy-of select="substring-before(concat($pText, '&quot;'), '&quot;')"/>

    <xsl:if test="contains($pText, '&quot;')">
      <xsl:text>"</xsl:text>

      <xsl:call-template name="escapeQuote">
        <xsl:with-param name="pText" select="substring-after($pText, '&quot;')"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:if>

</xsl:template>

Этот шаблон удаляет HTML-теги из входной строки. Я называю это так:

<xsl:variable name="output3">
    <xsl:call-template name="escapeQuote">
        <xsl:with-param name="pText">
        <xsl:call-template name="DataTableRow">
            ... with-params ...
        </xsl:call-template>
        </xsl:with-param>
    </xsl:call-template>
</xsl:variable>

Немедленно делаем:

<xsl:copy-of select="$output3"/>

Показывает, что HTML-теги больше не существуют и, следовательно, не существует двойных кавычек. Тем не менее, это показывает все мои HTML-теги:

<xsl:variable name="output3">
    <xsl:call-template name="DataTableRow">
        ... with-params ...
    </xsl:call-template>
</xsl:variable>
<xsl:copy-of select="$output3"/>

Спасибо, что прочитали все это - и кстати, я вижу другие сообщения, где код XSL красиво отформатирован и раскрашен. Это намного легче читать, но я не могу заставить его работать с кодом, который я публикую. Все-черный текст и левостороннее выравнивание. Я пытался исправить это, но у меня ничего не получается.

Править #3:

Дмитрий заметил, что цитата может быть использована буквально в атрибуте value скрытого поля ввода, поэтому я провел некоторые эксперименты с этим в виду. Кажется, что везде, куда я смотрю, есть готча.

<input value='something containing " literally'/>

Чтобы получить мое value= содержимое, завернутое апострофами вместо двойного кавычки, я попытался создать свой скрытый <input> Вот так:

<input>
  <xsl:attribute name="id">
    <xsl:value-of select="$id"/>
  </xsl:attribute>
  <xsl:attribute name="type">
    <xsl:text>hidden</xsl:text>
  </xsl:attribute>
  <xsl:attribute name="runat">
    <xsl:text>server</xsl:text>
  </xsl:attribute>
  <xsl:text> value='[</xsl:text>
  <xsl:copy-of select="$output"/>
  <xsl:text>]'</xsl:text>
</input>    

Это не работает, потому что тег <input...> отображается с атрибутом value= (и его содержимым) после закрытия </input>.

Поэтому я удалил элементы xsl:attribute и сформировал его с помощью xsl:text. К сожалению, использование < внутри xsl:text недопустимо и приводит к ошибке. Поэтому я изменил < на &lt;, а также соответствующий >. Это не породило никаких ошибок, но вызывает весь <input> и его содержимое, которое будет отображаться в виде строки при отображении страницы. (Я просматриваю страницу в Firefox).

Я не пробовал кодировать это с CDATA, потому что я уверен, что это тоже не сработает, и я получу те же результаты, что и последний - все будет отображаться в виде строки.

пожать плечами

Править #4:

Оджей рекомендовал отказаться от идеи поместить мой JSON в атрибут value= скрытого поля. Я все это обдумал. вместе, но не был уверен, насколько сильно мне придется менять свой код. Когда он показал на примерах, как мало мне придется изменить, я решил пойти на это.

К сожалению, есть еще один попавшийся.

<script type="text/javascript">

var hfDetails = [{ProductID: '000001',Title: '<h3>American Apparel Sheer Jersey Chemise X-Small-Asphalt</h3>',Condition: 'New',ListPrice: '<tr style="display:block">
    <td>
      <div class="datalabel">0List Price:</div>
    </td>
    <td class="datainfo" id="listprice">$24.99</td>
  </tr>',Price: '<tr style="display:block">
    <td>
      <div class="datalabel maroon">Sale:</div>
    </td>
    <td class="datainfo" id="price"><span class="bigmaroon">$15.49</span></td>
  </tr>',YouSave: '<tr style="display:block">
    <td>
      <div class="datalabel">You Save:</div>
    </td>
    <td class="datainfo" id="yousave"><span class="maroon">$9.50 (38%)</span></td>
  </tr>'},

 ....

]
</script>

Это вставка из отрисованной веб-страницы. Я получаю ошибку "Unterminated string literal", и она указывает на Апостроф прямо перед самым первым <tr> - на второй строке.

Я предполагаю, что это потому, что строка имеет пробелы, распространяющиеся на нее. несколько строк. Пробел-это как-есть от создания шаблона вызова. Я не знаю, как отключить этот пробел, и будет ли это вообще иметь значение. Я собираюсь погуглить об этом, но кто-нибудь знает, есть ли способ отключить пробелы для шаблона вызова?

2 3

2 ответа:

Попробуйте <xsl:copy-of select="$test"> вместо <xsl:value-of ... />

Также обратите внимание, <xsl:value-of /><xsl:copy-of />, если на то пошло), должно быть внутри шаблона, а не на корневом уровне <xsl:stylesheet >....</xsl:stylesheet> - выдает ошибку в моем отладчике XSLT

Итак, тест, который сработал для меня, был

<?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:variable name="test">
    <xsl:call-template name="demonstration" />
  </xsl:variable>

  <xsl:template match="/">
    <xsl:copy-of select="$test"/>
  </xsl:template>

  <xsl:template name="demonstration">
    <p>Just a test</p>
  </xsl:template>

</xsl:stylesheet>

Value-of будет получать значение переменной, и поскольку мы находимся в XML, значение будет таким же, как значение узла, то есть данные между тегами. Копия выводила бы именно что полную копию, теги и все


РЕДАКТИРОВАТЬ Согласно моему начатому комментарию, я имел в виду что-то вроде этого:

Выход из XSLT

<script type="text/javascript">
var hfDetails = [{"ProductID": "00001", "ListPrice": '<tr class="collapsed"><td class="datalabel">List Price:</td><td class="datainfo"></td></tr>', "YourPrice": '<tr><td class="datalabel">Price:</td><td class="datainfo">$23.99 & is elegible for <span class="freeshipping">FREE</span> shipping <a href="#">Details</a></td></tr>'},

... etc, etc, etc ...

];
</script>

Вместо скрытого поля ввода. Что это будет сделать, это создать глобальный объект массива JavaScript. в сущностях скачет шаг, требуемый

var details = $.parseJSON($("#[id*='hfDetails']").val());

Вы могли бы тогда просто сделать

var details = hfDetails;

И больше не нужно менять код.

Если вас беспокоит ускользание Апострофа и кавычек. Любой из них может быть использован для определения строка в javascript, а затем другой может быть безопасно использован в строке, т. е.

"ListPrice" : '<tr class="collapsed"><td class="datalabel">List Price:</td><td class="datainfo"></td></tr>'

Является действительным, и поэтому

"ListPrice" : "<tr class='collapsed'><td class='datalabel'>List Price:</td><td class='datainfo'></td></tr>"

Также обратите внимание, что вам не нужно заключать свойства объекта в кавычки, т. е.

"ProductID" : "00001"

Может быть просто

ProductID : "00001"

До тех пор, пока у вас нет пробелов в именах свойств

<xsl:value-of select="$test"/>

Вы должны использовать xsl:copy-of (или xsl:sequence рекомендуется в XSLT 2.0) - вместо xsl:value-of.

По определению, xsl:value-of выводит строковое значение результата вычисления выражения в его атрибуте select.

<xsl:copy-of> выводит (в порядке следования документов) все узлы node-set, указанные в его атрибуте select. Или, чтобы снова процитировать спецификацию W3C XSLT 1.0:

"элемент xsl:copy-of можно использовать для копирования a набор узлов в результирующее дерево без преобразования его в строку "

В XSLT 2.0 xsl:sequence может использоваться для вывода узлов набора узлов в любом желаемом порядке .