Как написать шаблон перехвата всех XSL, который также передает все параметры? - PullRequest
1 голос
/ 13 января 2012

Я пишу шаблон, который «расширяет» шаблоны, но у него есть некоторые проблемы.

<xsl:template match="*[@condition]" mode="#all">
<xsl:element name="condition">
  <xsl:attribute name="name">
    <xsl:value-of select="@condition"></xsl:value-of>
  </xsl:attribute>
  <xsl:apply-imports>
  </xsl:apply-imports>
</xsl:element>

Проблема в том, что в шаблонах, вызываемых с использованием <xsl:apply-imports>, отсутствуют параметры. Список параметров неизвестен, так как существует множество различных шаблонов, которые этот шаблон пытается расширить (отсюда mode="#all").

Есть ли хороший способ обойти это?


Дополнительный пример:

Рассмотрим два последних шаблона (только для чтения):

<xsl:template match="*" mode="mode1">
    <param name="p1"/>
</xsl:template>

<xsl:template match="*" mode="mode2">
    <param name="p2"/>
</xsl:template>

они называются где-то (только для чтения):

<xsl:apply-templates mode="mode1">
    <xsl:with-param name="mode1" select="$mode1"/>
</xsl:apply-templates>

<xsl:apply-templates mode="mode2">
    <xsl:with-param name="mode2" select="$mode2"/>
</xsl:apply-templates>

Может быть 100 с mode1, mode2, mode3, mode4 ... и имена не имеют шаблона.

Я хотел бы иметь глобальный шаблон, который оборачивает дополнительную информацию вокруг окончательных шаблонов. Что-то вроде:

<xsl:template match="*" mode="#all">
    <xsl:next-match/>
</xsl:element>

Проблема в том, что указанный выше глобальный шаблон не передает параметры в шаблоны.

Ответы [ 2 ]

1 голос
/ 13 января 2012

Вы можете либо использовать параметры туннеля, как это было предложено Максом Торо, либо вы можете просто передать один параметр , чьи дочерние элементы являются параметрами, которые будут нужны и распознаются различными шаблонами.

Как-то так :

<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:param name="pComposite" as="element()*">
   <param for="templateX" name="pA">
    12
   </param>
   <param for="templateY" name="pB">
    Some String
   </param>
 </xsl:param>

 <xsl:template match="*[@condition]">
  <condition name="{@condition}">
   <xsl:apply-imports>
     <xsl:with-param name="pComposite"
      select="$pComposite"/>
   </xsl:apply-imports>
  </condition>
 </xsl:template>
</xsl:stylesheet>
1 голос
/ 13 января 2012

Если ваша проблема в том, что когда вы вызываете <xsl:apply-imports>, он не включает параметры, переданные в текущий шаблон, вы можете использовать параметры туннеля. В шаблоне, который вы расширяете, отметьте ваши параметры следующим образом:

<xsl:param name="foo" tunnel="yes"/>

Также при передаче параметров:

<xsl:with-param name="foo" tunnel="yes"/>

Я также предлагаю использовать <xsl:next-match> вместо <xsl:apply-imports>.

...