Элемент упаковки в выбранной конструкции. Как улучшить? - PullRequest
1 голос
/ 18 мая 2010

Есть ли способ оптимизировать этот код.

<xsl:choose>
    <xsl:when test="val1 = val2">
        <xsl:apply-templates select="node"/>
    </xsl:when>
    <xsl:otherwise>
        <div>
            <xsl:apply-templates select="node"/>
        </div>
    </xsl:otherwise>
</xsl:choose>

Мне не нравится писать дважды одинаково <xsl:apply-templates select="node"/>.


Обновление:

Идея состоит в том, что в зависимости от результата сравнения нужно сделать одну из двух вещей:

  1. Просто напечатайте некоторую информацию (которую мы получаем после применения шаблона <xsl:apply-templates select="node"/>).

  2. Печать той же информации, но заранее " упаковка " в контейнере (div например).

Ответы [ 3 ]

0 голосов
/ 18 мая 2010

Используйте

<xsl:apply-templates select="node">
  <xsl:sort select="not(val1 = val2)"/>
</xsl:apply-templates>

Вот полный пример. Это преобразование:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <t>
        <xsl:apply-templates select="node">
          <xsl:sort select="not(val1 = val2)"/>
        </xsl:apply-templates>
  </t>
 </xsl:template>

 <xsl:template match="node[not(val1 = val2)]">
  <div>
     <node>
       <xsl:apply-templates/>
     </node>
  </div>
 </xsl:template>
</xsl:stylesheet>

при применении к этому документу XML :

<t>
  <node>
    <val1>1</val1>
    <val2>2</val2>
  </node>
  <node>
    <val1>3</val1>
    <val2>3</val2>
  </node>
</t>

дает желаемый, правильный результат:

<t>
   <node>
      <val1>3</val1>
      <val2>3</val2>
   </node>
   <div>
      <node>
         <val1>1</val1>
         <val2>2</val2>
      </node>
   </div>
</t>

Объяснение решения :

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

В приведенном выше преобразовании имеем:

<xsl:apply-templates select="node"> 
  <xsl:sort select="not(val1 = val2)"/> 
</xsl:apply-templates> 

Это означает, что результаты применения шаблонов к элементам с именем node, для которых верно, что val1=val2 будут появляться до результатов применения шаблонов к элементам с именем node, для которых val1=val2 не соответствует действительности. , Это потому что false сортирует до true.

Если это объяснение неясно, читателю предлагается прочитать больше о <xsl:sort>.

0 голосов
/ 19 мая 2010

Это возможно в этом простом примере, но если количество кода переноса и дубликата кода стоит беспокоить, у вас есть два варианта:

  1. ввести цепочку шаблонов с различными режимами:

    <!-- instead of choose -->
    <xsl:apply-template match="." mode="container" />
    ...
    <xsl:template match="container" mode="container">
        <xsl:apply-templates select="." mode="dup-group"/>
    </xsl:template>
    
    <xsl:template match="container[val1=val2]" mode="container">
        <div>
            <xsl:apply-templates select="." mode="dup-group"/>
        </div>
    </xsl:template>
    
    <xsl:template match="container" mode="dup-group">
        <xsl:apply-templates select="node"/>
        <!-- other duplicate code -->
        ...
    </xsl:template>
    
  2. переместить часть кода в отдельную импортированную таблицу стилей и переопределить правило шаблона в текущей таблице стилей:

    <xsl:template match="container[val1=val2]">
        <div>
            <xsl:apply-imports />
        </div>
    </xsl:template>
    
0 голосов
/ 18 мая 2010

xslt, который вы публикуете здесь, не очень оптимизируем. Если код, который вы не хотите дублировать, будет содержать более двух строк, вы можете оптимизировать его, создав именованный шаблон и вызвав его вместо этого. В этом примере это не имеет особого смысла, но вы поймете:

<xsl:when test="val1=val2">
  <xsl:call-template name="optimized"/>
</xsl:when>
<xsl:otherwise>
  <div>
    <xsl:call-template name="optimized"/>
  </div>
</xsl:otherwise>

И шаблон:

<xsl:template name="optimized">
  <xsl:apply-templates select="node"/>
</xsl:template>

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

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