Лучший подход для объединения нескольких проходов XSLT 1.0, которые обрабатывают одни и те же узлы - PullRequest
3 голосов
/ 21 июля 2011

Я делаю очень сложное преобразование XSLT 1.0 (в настоящее время используется 8 проходов XSLT). Я хочу объединить эти 8 проходов без объединения их в один файл (это было бы слишком сложно). Мое решение будет использовать xsl:include и exsl:node-set для объединения проходов и сохранения временных результатов в переменных.

Но у меня есть одна проблема: мое преобразование передает копии большинства узлов и модифицирует только определенные аспекты. Поэтому мне нужно обрабатывать одни и те же узлы на каждом проходе, но с разными xsl:template! Но как мне это сделать? Как сказать, что после первого прохода я хочу применить шаблоны из других таблиц стилей XSLT?

Очень упрощенный пример того, что я сейчас делаю (2 прохода XSLT):

Источник:

<h>something here</h>

После прохода XSLT 1:

<h someattribute="1">something here</h>

После прохода XSLT 2:

<h someattribute="1" somemoreattribute="2">something here, and even more</h>

Мой текущий подход заключается в том, чтобы дважды вызвать процессор XSLT и временно сохранить результаты на диске:

xsltproc stylesheet1.xsl input.xml >temp.xml
xsltproc stylesheet2.xsl temp.xml >finalresult.xml

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exsl="http://exslt.org/common"
                extension-element-prefixes="exsl"
                version="1.0">

  <xsl:import href="stylesheet1.xsl"/> <!-- assuming mode="stylesheet1" -->
  <xsl:import href="stylesheet2.xsl"/> <!-- assuming mode="stylesheet2" -->
  <xsl:import href="stylesheet3.xsl"/> <!-- assuming mode="stylesheet3" -->

  <xsl:template match="/">
    <xsl:variable name="temp1">
      <xsl:apply-templates select="." mode="stylesheet1"/>
    </xsl:variable>
    <xsl:variable name="temp2">
      <xsl:apply-templates mode="stylesheet2" select="exsl:node-set($temp1)"/>
    </xsl:variable>
    <xsl:apply-templates mode="stylesheet3" select="exsl:node-set($temp2)"/>
  </xsl:template>

</xsl:stylesheet>

Недостатком является то, что вам нужно изменить исходные таблицы стилей, добавив соответствующие атрибуты modeкаждому xsl:template и xsl:apply-templates.Вы все еще можете заставить таблицы стилей работать независимо друг от друга, добавив в каждый из них дополнительный шаблон:

<xsl:template match="/">
  <xsl:apply-templates select="." mode="stylesheet1"/>
</xsl:template>
0 голосов
/ 21 июля 2011

Почему бы не использовать

<xsl:param name="iteration"/>

И передать номер итерации в таблицу стилей? Затем вы можете использовать его следующим образом

<xsl:if test="$iteration = 1">
  ...
</xsl:if>

... или в других контекстах

Вы можете установить параметр с помощью

javax.xml.transform.Transformer.setParameter("iteration", 1);

Или с муравьем:

<xslt ...>
  <param name="iteration" expression="1"/>
</xslt>
...