#xslt #copy #xls
#xslt #Копировать #xls
Вопрос:
Во-первых, я должен сказать, что я новичок в терминах XSLT.
Хотя точный контекст может быть не столь релевантным (и может быть слишком запутанным), я приведу его ниже. У меня есть цепное преобразование, которое выглядит следующим образом:
-
Input.xml
является входным файлом для этого преобразования, которое выполняется с помощьюtransform.xsl
. Результатом этого преобразования являетсяoutput.xml
.transform.xml
содержит классический пользовательскийxsl:function
:xsl:function name="my:f" xsl:sequence select=".. xpath .." xsl:function
-
Результатом шага 1 (
output.xml
) для шага 2 является новый transformer (transform2.xsl
), который будет использовать некоторые другие входные данные XML (скажем,input2.xml
).
Что я хотел бы сделать, так это полностью скопировать xsl:function
узел (присутствующий в transform.xsl
на шаге 1) в output.xml
, чтобы его можно было использовать на шаге 2. В этом случае не требуется никаких обновлений / изменений для xsl:function
во время его копирования (просто простая копия узла). Обратите внимание, что я не хочу копировать xsl:function
только тогда, когда присутствует данный элемент ввода (из input.xml
). Но, скорее, я хочу копировать его всегда, независимо от того, что такое input.xml
.
Теперь я знаю, что это можно сделать, создав отдельный файл, содержащий my xsl:function
, а затем используя xsl:import
для включения этого файла оба преобразования ( transform.xml
и transform2.xml
).
Но я хотел бы знать, существуют ли другие способы достижения этого (.. без наличия отдельного файла, в котором объявлена / определена функция)?
Заранее спасибо,
M.
Комментарии:
1. @user414366: Непонятно, почему вы хотите динамически создавать XSLT 2.0. В случае, если вы не можете изменить первую таблицу стилей, чтобы изолировать объявление функции в общем модуле таблицы стилей, вы можете импортировать первую таблицу стилей во вторую, чтобы использовать функцию, позаботившись о применении шаблонов через
@mode
, чтобы избежать импортированных шаблонов.2. @Alejandro: Я использую сторонние таблицы стилей и хотел бы свести изменения к минимуму. Вот почему импорт всей таблицы стилей (transform.xsl) из другой таблицы стилей (transform2.xsl) в моем случае был бы нежелателен. Кроме того, transform2.xsl генерируется динамически, поэтому в данном случае динамическая генерация xsl: функций не так уж и плоха.
3. Абсолютно нет необходимости копировать функцию в выходные данные — она может (и должна!) просто импортируется как часть модуля таблицы стилей. Копирование функции является негативной работой — это приводит к снижению производительности, большему количеству движущихся частей (кода) и возможности ошибок и значительно влияет на читаемость, понятность и ремонтопригодность продукта. Если я получу этот неправильный код, одним из первых рефакторингов, который я бы сделал, будет удаление кода копирования и помещение функции в отдельный импортируемый модуль таблицы стилей. Вам нужно учиться, особенно если вы новичок!
4. @Dimitre: Копирование кода — это то, что я тоже не поощряю. После дополнительных размышлений я решил перенести общую функцию в отдельный файл.
Ответ №1:
Вы можете получить доступ к документу таблицы стилей, document('')
выполнив это, например
<xsl:template match="/*">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:copy-of select="document('')/xsl:stylesheet/xsl:function"/>
<xsl:apply-templates/>
</xsl:stylesheet>
</xsl:template>
следует скопировать любые xsl:function
элементы в таблице стилей в результирующее дерево.
[править / править код]После редактирования кажется, что вы хотите скопировать функцию с определенным именем: если вы хотите скопировать функцию с определенным именем, вы могли бы сделать, например
<xsl:copy-of select="document('')/xsl:stylesheet/xsl:function[
resolve-QName(@name, .) eq QName('http://example.com/ns', 'f')]"/>
где f
— локальное имя функции и http://example.com/ns
— пространство имен, в котором определена функция.
Комментарии:
1. Большое спасибо за ваш ответ, Мартин! Вы ответили так быстро .. и так хорошо 🙂 Я не знал, что вы можете использовать document () таким образом, чтобы добраться до узла document. Сегодня я кое-что узнал 🙂
Ответ №2:
Вы можете использовать document()
встроенную функцию, которая вернет документ таблицы стилей для emtpy URI. Затем вы можете просто скопировать элемент в выходные данные.
Комментарии:
1. Лусеро, я тоже хотел бы поблагодарить тебя! Но Мартин ответил первым, поэтому на этот раз я бы отметил его ответ.