Атрибут имени шаблона вызова XSLT

Кажется, я не могу использовать Xpath в атрибуте имени элемента call-template. Как я могу обойти это? Любая помощь/мысли были бы потрясающими!

<xsl:for-each select="child::knomaddb/Content/Videos">
        <xsl:result-document method="xhtml" href="{local-name()}.html">
            <html>
                <body>
                    <h1>Knomad</h1>
                    <h2>{local-name()} Videos</h2>
                    <table border="1">
                        <tr bgcolor="#9acd32">
                            <th>Title</th>
                            <th>Video</th>
                            <th>Description</th>
                            <th>Comments</th>
                        </tr>
                        <xsl:for-each select="Video">
                            <xsl:call-template name="{ancestor::local-name()}"/>
                        </xsl:for-each>
                    </table>
                </body>
            </html>
        </xsl:result-document>
    </xsl:for-each>

person Victor Kmita    schedule 02.12.2011    source источник
comment
Пробовали ли вы использовать apply-templates и правила шаблонов для решения своей проблемы? Инструкция call-template не принимает выражение xpath в атрибуте имени, вы должны явно указать имя.   -  person riff    schedule 03.12.2011
comment
Помимо того факта, что вы, кажется, пытаетесь заново изобрести xsl:apply-templates, ваше выражение XPath ancestor::local-name() не является допустимым выражением XPath, и если бы это было так, оно, вероятно, выбрало бы более одного имени, поскольку узел имеет несколько предков.   -  person Michael Kay    schedule 03.12.2011


Ответы (2)


Кажется, я не могу использовать Xpath в атрибуте имени элемента call-template. Как я могу обойти это?

Хороший вопрос, +1.

Вы не можете. Но вместо этого вы можете использовать <xsl:apply-templates>.

Вот краткая демонстрация:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:double="double" xmlns:incr="incr" xmlns:my="my:my"
exclude-result-prefixes="double incr my"
>
  <xsl:output method="text"/>

   <double:double/>
   <incr:incr/>

   <xsl:variable name="vFuncDouble"
        select="document('')/*/double:*[1]"/>

   <xsl:variable name="vFuncIncr"
        select="document('')/*/incr:*[1]"/>

   <xsl:function name="my:double">
     <xsl:param name="arg1" />

      <xsl:sequence select="2*$arg1"/>
   </xsl:function>

   <xsl:function name="my:incr">
     <xsl:param name="arg1" />

      <xsl:sequence select="1+$arg1"/>
   </xsl:function>

    <xsl:template name="double" match="double:*">
      <xsl:param name="arg1"/>

      <xsl:sequence select="my:double($arg1)"/>
    </xsl:template>

    <xsl:template name="incr" match="incr:*">
      <xsl:param name="arg1"/>

      <xsl:sequence select="my:incr($arg1)"/>
    </xsl:template>

    <xsl:function name="my:apply">
      <xsl:param name="pFun" as="element()"/>
      <xsl:param name="arg1"/>

      <xsl:apply-templates select="$pFun">
        <xsl:with-param name="arg1" select="$arg1"/>
      </xsl:apply-templates>
    </xsl:function>

    <xsl:template match="/">
     <xsl:sequence select="my:apply($vFuncIncr, my:apply($vFuncDouble,2))"/>
    </xsl:template>
</xsl:stylesheet>

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

5

Обратите внимание:

Можно передать в качестве параметра (первого аргумента) my:apply() любую "функцию" и my:apply() применит ее ко второму аргументу.

Используя тот же принцип, библиотека FXSL реализовала функции высшего порядка (HOF) в XSLT 1.0 и XSLT 2.0 -- подробнее здесь.

В готовящемся XPath 3.0 функции впервые являются объектами первого класса в Модель данных Xpath (XDM).

person Dimitre Novatchev    schedule 02.12.2011

Это по дизайну. xsl:call-template определяется следующим образом:

<!-- Category: instruction -->
<xsl:call-template
  name = qname>
  <!-- Content: xsl:with-param* -->
</xsl:call-template>

Атрибут name должен быть полным именем, а не XPath. выражение.

Источники:

person Wayne    schedule 02.12.2011