Копирование элемента (xsl: функции) из таблицы стилей в XML-файл «результат»

#xslt #copy #xls

#xslt #Копировать #xls

Вопрос:

Во-первых, я должен сказать, что я новичок в терминах XSLT.

Хотя точный контекст может быть не столь релевантным (и может быть слишком запутанным), я приведу его ниже. У меня есть цепное преобразование, которое выглядит следующим образом:

  1. Input.xml является входным файлом для этого преобразования, которое выполняется с помощью transform.xsl . Результатом этого преобразования является output.xml . transform.xml содержит классический пользовательский xsl:function :

     xsl:function name="my:f"
         xsl:sequence select=".. xpath .."   
    xsl:function
      
  2. Результатом шага 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. Лусеро, я тоже хотел бы поблагодарить тебя! Но Мартин ответил первым, поэтому на этот раз я бы отметил его ответ.