XSLT - применить шаблон к результату шаблона вызова - PullRequest
4 голосов
/ 18 декабря 2011

Можно ли применить шаблон к результату вызова шаблона?

Например, xml и 2 xslt ниже.

index.xml:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <book>
    <title>Ethics</title>
  </book>
  <book>
    <title>Beyond Good and Evil</title>
  </book>
</root>

index2.xsl

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template match="/" name="temp2">
    <foo>
    <xsl:for-each select="//book">
      <bar><xsl:value-of select="."/></bar>
    </xsl:for-each>
    </foo>
  </xsl:template>
</xsl:stylesheet>

и index.xsl вызывает index2.xsl

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
<xsl:include href="index2.xsl" />
<!-- apply a template to the <xsl:call-template name="temp2" /> result -->
</xsl:stylesheet>

Есть ли способ применить шаблон к результату <xsl:call-template name="temp2" /> вindex.xsl?

Заранее спасибо.

1 Ответ

8 голосов
/ 18 декабря 2011

Есть ли способ применить шаблон к результату <xsl:call-template name="temp2" /> в index.xsl?

Да, это называется multiпроходная обработка .Единственная особенность заключается в том, что в XSLT 1.0 вы должны применять зависящую от реализации функцию расширения xxx:node-set() к любому промежуточному результату, который в общем случае будет печально известного типа RTF (Result Tree Fragment) и, следовательно, должен будет быть преобразован в обычныйtree.

Вот полный пример многопроходной обработки (я использую xsl:apply-templates, а не xsl:call-template, но вы можете свободно изменять этот пример, чтобы использовать именованные шаблоны и xsl:call-template вместо):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates select="num"/>
  </xsl:variable>

  <xsl:apply-templates mode="pass2"
    select="ext:node-set($vrtfPass1)/*"/>
 </xsl:template>

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

 <xsl:template match="num" mode="pass2">
  <num><xsl:value-of select=". * ."/></num>
 </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>

требуемый результат (содержимоелюбые элементы num удваиваются в первом проходе, а затем возводятся в квадрат во втором проходе) :

<num>4</num>
<num>16</num>
<num>36</num>
<num>64</num>
<num>100</num>
<num>144</num>
<num>196</num>
<num>256</num>
<num>324</num>
<num>400</num>

II.В XSLT 2.0

«Тип» RTF был упразднен, поэтому намного проще указать многопроходную обработку , которая становится практически неотличимой от функциональной композиции, как показано нижеэквивалентное преобразование показывает:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:sequence select="my:squareAll(my:doubleAll(*))"/>
 </xsl:template>

 <xsl:function name="my:doubleAll" as="element()*">
  <xsl:param name="pElems" as="element()*"/>

  <xsl:for-each select="$pElems">
   <xsl:copy>
    <xsl:sequence select=". + ."/>
   </xsl:copy>
  </xsl:for-each>
 </xsl:function>

 <xsl:function name="my:squareAll" as="element()*">
  <xsl:param name="pElems" as="element()*"/>

  <xsl:for-each select="$pElems">
   <xsl:copy>
    <xsl:sequence select=". * ."/>
   </xsl:copy>
  </xsl:for-each>
 </xsl:function>
</xsl:stylesheet>

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

<num>4</num>
<num>16</num>
<num>36</num>
<num>64</num>
<num>100</num>
<num>144</num>
<num>196</num>
<num>256</num>
<num>324</num>
<num>400</num>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...