Изменить приоритет шаблона или пересмотреть код? - PullRequest
0 голосов
/ 26 января 2020

Вот код, который, по сути, дает правильный вывод. Но речь идет об оптимизации внутренних процессов. Условно их можно разделить на 2 части.

  • ОСНОВНОЙ алгоритм (набор кодов, создающих цепочки отношений)

  • УДАЛИТЬ шаблон (удаляет ненужные узлы, которые не удовлетворяют условиям)

Приоритет выполнения шаблонов, который я могу оценить в тестах, равен 1- [MAIN], затем, наконец, 2- [DELETE]. Но дело в том, что обратный порядок 1- [DELETE], а затем 2- [MAIN], как я полагаю, был бы более эффективным решением. В этом случае для обработки MAIN останутся только необходимые узлы, образующие цепочки (поэтому внутреннее условие дополнительной проверки также больше не потребуется). Но пока алгоритм MAIN вынужден делать дополнительные, ненужные вычисления. Я попытался использовать дополнительный атрибут приоритета для шаблонов, но, похоже, он ничего не изменил (потому что, как я понимаю, эти два шаблона не конфликтуют друг с другом).

XSLT-код

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common">
  <xsl:key name="Object-By-id" match="Object" use="@id"/>
  <xsl:key name="Object-By-parent-id" match="Object" use="string(@id-parent)"/>

  <xsl:variable name="fold-rtf">
    <xsl:apply-templates select="/" mode="fold"/>
  </xsl:variable>
  <xsl:variable name="folded-tree" select="exslt:node-set($fold-rtf)"/>

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

 <xsl:template match="Object[not(@status='0')]"/>      <!-- [DELETE] pattern -->

  <xsl:template match="Object[@status=0]/@*[last()]">  <!-- [MAIN] -->
    <xsl:variable name="current" select=".."/>
    <xsl:copy/>
    <xsl:for-each select="$folded-tree">
      <xsl:for-each select="key('Object-By-id',$current/@id)">
        <xsl:attribute name="chain-text">
          <xsl:for-each select="ancestor-or-self::*">
            <xsl:sort select="@rank"/>
            <xsl:if test="position()!=1"> | </xsl:if>
            <xsl:value-of select="concat(@text1,' ',@text2)"/>
          </xsl:for-each>
        </xsl:attribute>
        <xsl:for-each select="ancestor-or-self::*">
          <xsl:sort select="@rank"/>
          <xsl:attribute name="level-{position()}">
            <xsl:value-of select="concat(@text,' | ',@text2)"/>
          </xsl:attribute>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="/|*" mode="fold">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="key('Object-By-parent-id',string(@id))" mode="fold">
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

В сумме у меня есть следующие вопросы:

a) Несмотря на попытку, есть ли вид принудительного принуждения к изменению приоритета плана выполнения шаблона?

b) Или какие-либо другие соображения?

здесь примерная панель просто для демонстрации того, сколько циклов вычислений может быть потенциально сохранено. https://xsltfiddle.liberty-development.net/jz1Q1y5

...