Выполнение цепочки преобразований в XSLT - PullRequest
0 голосов
/ 21 февраля 2019

Я пытаюсь преобразовать документ XML с помощью серии преобразований таблиц стилей XSL в oXygen.Я нашел вопрос Является ли последовательное соединение xslt принятой практикой? и ответ Димитра Новатчева (ниже) великолепен: он отлично работает, как изложено в двух проходах.Однако я не могу заставить это работать на третий проход.

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:apply-templates select="/*/*"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

Я попытался добавить вторую переменную, как показано ниже (в моей задаче я называю именованные шаблоны вместо применения ко всему документу).То, что я называю template2, должно применяться к выводу преобразования, выполняемого template1.

Должен ли я объявлять переменную $ vPass2 где-то в пределах template1, а не там же, где я объявляю $ vPass1?Или я не понимаю, как это работает?

<xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:call-template name="template1"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2" select="$vPass1/*"/>
  <xsl:variable name="vPass2" >
   <xsl:call-template name="template2"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass3" select="$vPass2/*"/>
 </xsl:template>

Спасибо

1 Ответ

0 голосов
/ 21 февраля 2019

При применении другого шага - здесь третьего - вы должны также поместить результат второго прохода в переменную.

Таким образом, если добавить к примеру из связанного ответа, трехшаговое решение можетвыглядеть следующим образом:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
  <xsl:output omit-xml-declaration="yes" indent="yes" />

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:variable name="vPass1">
        <xsl:apply-templates select="/*/*" />
      </xsl:variable>
      <xsl:variable name="vPass2">
        <xsl:apply-templates mode="pass2" select="$vPass1/*" />
      </xsl:variable>
      <xsl:variable name="vPass3">
        <xsl:apply-templates mode="pass3" select="$vPass2/*" />
      </xsl:variable>
      <!-- Display the final result -->
      <xsl:copy-of select="$vPass3"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="num[. mod 2 = 1]">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="num" mode="pass2">
    <xsl:copy>
      <xsl:value-of select=". *2"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="num" mode="pass3">
    <xsl:copy>
      <xsl:value-of select=". + 1"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Применяется к этому входному XML

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

Результат (2 * x + 1)

<nums>
   <num>3</num>
   <num>7</num>
   <num>11</num>
   <num>15</num>
   <num>19</num>
</nums>

Относительныйна ваш специальный вопрос, ваш второй <xsl:apply-templates mode="pass2" select="$vPass1/*"/> не входит в переменную, поэтому его результат не будет передан на третий шаг.

...