XSLT: объединение таблиц стилей - PullRequest
0 голосов
/ 15 июля 2009

В настоящее время я использую две таблицы стилей, чтобы получить желаемый результат. Первая таблица стилей (pass1.xsl) выполняет реальную работу, а вторая таблица стилей (pass2.xsl) удаляет дубликаты, обеспечивая незначительные обновления форматирования.

У меня вопрос, могу ли я выполнить оба действия в одной таблице стилей.
Когда я смотрю на контент, у меня не складывается впечатление, что я могу с помощью xsl: functions, потому что обе таблицы стилей содержат совпадения шаблонов, которые конфликтуют, если я копирую / вставляю из второго в первый. IE:

pass1.xsl:

<xsl:template match="xs:complexType">
  <xsl:param name="prefix" />       
  <xs:complexType name="{my:updateName($prefix, @name)}">

    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent -->
    <xsl:choose>
      <xsl:when test="*[name()='xs:complexContent']">
        <xsl:apply-templates select="node()" />
      </xsl:when>
      <xsl:otherwise>
        <xs:sequence>
          <xsl:apply-templates select="node()" />
        </xs:sequence>              
      </xsl:otherwise>
    </xsl:choose>
  </xs:complexType>
  <xsl:apply-templates select=".//xs:element" />
</xsl:template>

pass2.xsl:

<xsl:template match="xs:complexType">
  <xsl:copy>
    <xsl:apply-templates select="*|@*"/>
  </xsl:copy>
</xsl:template>

Повторюсь - цель состоит в том, чтобы запустить только одну таблицу стилей для получения окончательного результата. Бежать два не сложно, но было бы неплохо, если бы не пришлось. Я смотрю на копирование / вставку в оригинал и заставляю его работать, или импорт / включает в себя то, на что я должен смотреть? Я предпочел бы иметь только один файл таблицы стилей - чтобы минимизировать вероятность ошибочного удаления вспомогательного файла.

1 Ответ

1 голос
/ 15 июля 2009

Вы должны использовать разные режимы для шаблонов (для этого потребуется добавить атрибут mode для всех операторов xsl:template и xsl:apply-templates). Затем ваш шаблон для корневого узла в режиме по умолчанию сначала запустит корневой шаблон в первом режиме, а затем передаст результат этого корневому шаблону во втором режиме. Для этого вам понадобится возможность обрабатывать фрагмент результирующего дерева (то, что создают конструкторы элементов) как набор узлов (то, к чему вы можете применять шаблоны и запрашивать их через XPath) - стандартного способа сделать это не существует. , но exsl:node-set является стандартом де-факто для этого (обратите внимание, что полный список процессоров, поддерживающих его, больше, чем на этой странице - например, .NET XslCompiledTransform поддерживает его). Итак:

<xsl:template match="/">
   <xsl:variable name="round1-output">
     <xsl:apply-templates select="/" mode="round1" />
   </xsl:variable>
   <xsl:apply-templates select="exsl:node-set($round1-output)" mode="round2" />
</xsl:template>

<xsl:template match="/" mode="round1">
   ...
   <xsl:apply-templates mode="round1" />
   ...
</xsl:template>

<xsl:template match="/" mode="round2">
   ...
   <xsl:apply-templates mode="round2" />
   ...
</xsl:template>

...

<xsl:template match="xs:complexType" mode="round1">
  <xsl:param name="prefix" />           
  <xs:complexType name="{my:updateName($prefix, @name)}">
    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent -->
    <xsl:choose>
      <xsl:when test="*[name()='xs:complexContent']">
        <xsl:apply-templates select="node()" mode="round1"/>
      </xsl:when>
      <xsl:otherwise>
        <xs:sequence>
          <xsl:apply-templates select="node()" mode="round1"/>
        </xs:sequence>                          
      </xsl:otherwise>
    </xsl:choose>
  </xs:complexType>
  <xsl:apply-templates select=".//xs:element" mode="round1"/>
</xsl:template>

<xsl:template match="xs:complexType" mode="round2">
  <xsl:copy>
    <xsl:apply-templates select="*|@*" mode="round2"/>
  </xsl:copy>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...