оптимизация шаблона xslt - PullRequest
       5

оптимизация шаблона xslt

2 голосов
/ 18 ноября 2008

У меня есть следующий код xslt:

<xsl:template match="table_terms_and_abbr">
    <informaltable frame='none' colsep='none' rowsep='none'>
        <tgroup cols='2' align='left'>
            <colspec colnum="1" colwidth='1*'/>
            <colspec colnum="2" colwidth='1*'/>
            <xsl:apply-templates/>
        </tgroup>     
    </informaltable>
</xsl:template>

и следующий XML, который он обрабатывает:

<table_terms_and_abbr>
        <tblrow_hdr>Name ,, Description</tblrow_hdr>
        <tbody>
            <tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
            ...
        </tbody>    
</table_terms_and_abbr>

Теперь я хочу улучшить xslt, перемещая следующие строки внутри table_terms_and_abbr:

<tblrow_hdr>Name ,, Description</tblrow_hdr>
<tbody>

</tbody>

Так что у меня будет что-то вроде:

<xsl:template match="table_terms_and_abbr">
    <informaltable frame='none' colsep='none' rowsep='none'>
        <tgroup cols='2' align='left'>
            <colspec colnum="1" colwidth='1*'/>
            <colspec colnum="2" colwidth='1*'/>
             <xsl:call-template name="tblrow_hdr">
                  BOT ,, &j_bot;                      * ???? *
             </xsl:call-template>
            <tbody>
            <xsl:apply-templates/>
            </tbody>
        </tgroup>     
    </informaltable>
</xsl:template>

Строка, помеченная * ???? * не работает. Я использовал saxon9 (таблица стилей xslt 2.0) на платформе Linux и получил эту ошибку:

XTSE0010: В xsl: call-template запрещены никакие символьные данные

Я знаю, как передать атрибуты в шаблон, т.е.:

<xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>

а как передать свободный текст?

Идея состоит в том, чтобы перенести в шаблон все статические данные и в xml использовать только переменные данные, т.е.

<table_terms_and_abbr>
    <tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
    ...
</table_terms_and_abbr>

Подробнее
Моим требованием было создать упрощенный синтаксис для определения повторяющихся таблиц для нашей документации DocBook. Для этого я создал общий шаблон с именем tblrow, который разделит строку, разделенную ",,", на отдельные сущности и создаст список записей в строке таблицы.
Каждая запись может быть простой строкой, ENTITY или другим шаблоном. Так как номера параметров не определены (таблицы могут иметь разное количество ячеек), я не могу использовать стандартные параметры для шаблонов и строку с разделителями. Если я хочу, чтобы одна из записей таблицы содержала ссылку на какое-то место в документе, я не могу снова использовать параметры, поскольку не могу передать шаблон внешней ссылки в качестве параметра.
Основная причина не менять шаблон tblrow в том, что он работает :) и это довольно сложно. Мне потребовались годы, чтобы достичь этого, и я не совсем понимаю, как это работает :).

Теперь у меня есть несколько переменных, которые могут управлять отображаемым выводом, например tblrow_hdr, который будет подчеркивать и выделять текст в каждой записи. Так как tblrow_hdr является общим для всех table_terms_and_abbr таблиц, для меня просто логично, что я не имею этого в xml, вместо этого поставлю вызов tblrow_hdr внутри шаблона table_terms_and_abbr и вот я застрял.

Ответы [ 3 ]

3 голосов
/ 18 ноября 2008

Я знаю, как передать атрибуты в шаблон, т.е.:

<xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>

а как передать свободный текст?

Передать текст как содержимое элемента xsl:with-param.

Преобразования XSL 11.6 Передача параметров в шаблоны

<xsl:with-param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:with-param>

Параметры передаются в шаблоны с использованием элемента xsl:with-param. Обязательный атрибут name указывает имя параметра (переменная, значение которой привязка должна быть заменена). Значением атрибута имени является QName , которое расширяется, как описано в [2.4 Квалифицированных имен] . «xsl: with-param» допускается как в xsl:call-template, так и в xsl:apply-templates. Значение параметра указывается так же, как для xsl:variable и xsl:param. Текущий узел и текущий список узлов, используемые для вычисления значения, указанного элементом xsl:with-param, являются такими же, как те, которые используются для элемента xsl:apply-templates или xsl:call-template, в котором это происходит. Передача параметра x в шаблон, который не имеет элемента xsl:param для x , не является ошибкой; параметр просто игнорируется.

В этом примере определяется именованный шаблон для пронумерованного блока с аргументом для управления форматом числа.

<xsl:template name="numbered-block">
  <xsl:param name="format">1. </xsl:param>
  <fo:block>
    <xsl:number format="{$format}"/>
    <xsl:apply-templates/>
  </fo:block>

<xsl:template match="ol//ol/li">
  <xsl:call-template name="numbered-block">
    <xsl:with-param name="format">a. </xsl:with-param>
  </xsl:call-template>
</xsl:template>
1 голос
/ 21 ноября 2008
> Since the parameter numbers are
> undefined (the tables can have
> different number of cells) i can't use
> a standard parameters for the
> templates and used delimited string.

На самом деле это не так.

Вот пример

<xsl:with-param/>
, тело которого представляет собой набор узлов, который может состоять из разного количества элементов при разных вызовах:
    <xsl:template match="/">
      <xsl:variable name="vrtfTParams">
        <p>xxx</p>
        <p>yyy</p>
        <p>zzz</p>
      </xsl:variable>

      <xsl:call-template name="makeTable">
        <xsl:with-param name="pTParams"
         select="msxsl:node-set($vrtfTParams)/*"/>
      </xsl:call-template>
    </xsl:template>

Шаблон "makeTable" может быть таким простым:

    <xsl:template name="makeTable">
      <xsl:param name="pTParams"/>

      <table>
        <tr>
          <xsl:for-each select="$pTParams">
            <td>
              <xsl:value-of select="."/>
            </td>
          </xsl:for-each>
        </tr>
      </table>
    </xsl:template>

Функция расширения msxsl: node-set () может использоваться с процессором Microsoft XSLT. Большинство других процессоров поддерживают функцию расширения exslt: node-set () (Microsoft .Net XSLT-процессор XslCompiledTransform также поддерживает ее).

В случае, если содержимое $ vrtfTParams не генерируется динамически (как в этом случае), никакой функции xxx: node-set () не требуется, поскольку содержимое может быть передано как это:

 <xsl:with-param name="pTParams"
   select="document('')/*/xsl:variable[name()=vrtfTParams)/*"/>

Здесь $ vrtfTParams должен быть определен глобально (дочерний элемент ).

В XSLT 2.0 (и XPath 2.0) отсутствует тип RTF и вообще не требуется функция расширения xxx: node-set ().

Надеюсь, это помогло.

Приветствия

Димитр Новатчев

1 голос
/ 19 ноября 2008

Вы можете передать дополнительные строковые данные в качестве параметра:

и в вызываемом шаблоне определите этот параметр:

Или вы можете определить global <xsl:variable/> или <xsl:param/> и ссылаться на него непосредственно в вызываемом шаблоне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...