Сортировка набора узлов перед передачей в xsl: for-each - PullRequest
8 голосов
/ 08 апреля 2010

У меня есть ситуация, когда перебираю отсортированный набор узлов и применяю шаблон для каждого из узлов:

<div id="contractscontainer">
  <xsl:for-each select="document">
    <xsl:sort select="content[@name='ClientName']/text()" />
    <xsl:apply-templates select="." mode="client-contract" />
  </xsl:for-each>
</div>

Я хочу сделать что-то особенное с «первыми» 5 узлами в наборе узлов и отобразить их как вложенный элемент. Проблема в том, что они должны быть в том же порядке, как если бы они были отсортированы (как в цикле).

Я планировал сделать это, используя два xsl:for-each элемента, каждый с правильными узлами, выбранными из набора. Я не могу сделать это, однако, потому что они должны быть отсортированы до Я могу выбрать "первый" 5.

Пример:

<div id="contractscontainer">
  <div class="first-five">
    <xsl:for-each select="document[position() < 6]">
      <xsl:sort select="content[@name='ClientName']/text()" />
      <xsl:apply-templates select="." mode="client-contract" />
    </xsl:for-each>
  </div>
  <div class="rest-of-them">
    <xsl:for-each select="document[position() > 5]">
      <xsl:sort select="content[@name='ClientName']/text()" />
      <xsl:apply-templates select="." mode="client-contract" />
    </xsl:for-each>
  </div>
</div>

Не думаю, что это сработает, потому что я выбираю узлы по позиции до сортировки, но я не могу использовать xsl:sort вне xsl:for-each.

Я неправильно подхожу к этому?

Редактировать : Мое текущее решение состоит в том, чтобы отсортировать их и сохранить отсортированный набор в другой переменной:

<xsl:variable name="sorted-docs">
  <xsl:for-each select="document">
    <xsl:sort select="content[@name='ClientName']/text()" />
    <xsl:copy-of select="." />
  </xsl:for-each>
</xsl:variable>

Работает, но есть ли лучший способ?

1 Ответ

14 голосов
/ 08 апреля 2010

Вот один из способов сделать это в XSLT 1.0 без необходимости использования функции расширения xxx: node-set () :

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

 <xsl:template match="/*">
  <html>
   <div class="first-five">
     <xsl:apply-templates select="num">
       <xsl:sort select="." data-type="number"/>
       <xsl:with-param name="pStart" select="1"/>
       <xsl:with-param name="pEnd" select="5"/>
     </xsl:apply-templates>
   </div>
   <div class="rest-of-them">
     <xsl:apply-templates select="num">
       <xsl:sort select="." data-type="number"/>
       <xsl:with-param name="pStart" select="6"/>
     </xsl:apply-templates>
   </div>
  </html>
 </xsl:template>

 <xsl:template match="num">
  <xsl:param name="pStart"/>
  <xsl:param name="pEnd" select="999999999999"/>

  <xsl:if test="position() >= $pStart
              and
                not(position() > $pEnd)">
   <p><xsl:value-of select="."/></p>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>

Когда указанное преобразование применяется к этому простому документу XML :

<nums>
  <num>5</num>
  <num>3</num>
  <num>6</num>
  <num>8</num>
  <num>4</num>
  <num>1</num>
  <num>9</num>
  <num>2</num>
  <num>7</num>
  <num>10</num>
</nums>

желаемый результат получен :

<html>
    <div class="first-five">
        <p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
        <p>5</p>
    </div>
    <div class="rest-of-them">
        <p>6</p>
        <p>7</p>
        <p>8</p>
        <p>9</p>
        <p>10</p>
    </div>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...