Сортировка XSLT в сочетании с предшествующим братом :: - PullRequest
5 голосов
/ 12 мая 2011

В цикле foreach я хочу использовать предшествующий брат ::

<for-each..>
    <xsl:sort select="type"/>
    <xsl:when test="preceding-sibling::data[1]/type != type

проблема заключается в том, что "тип" внутри foreach сравнивается с несортированным предшествующим братом, например,

data1/type = 1 
data2/type = 2
data3/type = 1

будет сравнивать во втором цикле silbling = 2 (оригинал не отсортирован) и type = 1 (так как он отсортирован)

есть ли способ обойти это?

ОБНОВЛЕНИЕ: мое намерениеследующий

before             after
data/type2         type1 value1
data/type1         type1 value2 
data/type1         and speaking in HTML a spacer here (I compare type2:value to preceding-sibling value
data/type2         type2 value1
                   type2 value2

У меня есть несортированный список адресов, где тип является городом, и мне нужна таблица HTML, отсортированная по городам, и что-то делать в зависимости от значений и других полей (эта часть работает, но так как сравнение с предшествующим родным братом не работает в отсортированном для каждого, я получил проблему

Ответы [ 4 ]

4 голосов
/ 13 мая 2011

Это решение теперь работает для меня:

    <xsl:variable name="sortedcopy">
      <xsl:for-each select="node1/node2/node3/data">
        <xsl:sort select="type" order="ascending"/>
        <xsl:copy-of select="current()"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="relItems" select="MSXML:node-set($sortedcopy)" />
    <xsl:for-each select="$relItems/data">
      <xsl:if test="not(preceding-sibling::data[1]/id = id)">
        <hr/>
      </xsl:if>
      <xsl:value-of select="val"/>
    </xsl:for-each>
1 голос
/ 12 мая 2011

Вы пытаетесь сгруппировать элементы данных по типу?Дайте нам знать, что вы пытаетесь сделать, и мы, вероятно, можем помочь (как сказал @Michael Kay).

Один вариант (в XSLT 2.0 или с расширением набора узлов) состоит в том, чтобы отсортировать-скопироватьэлементы данных в новую переменную, затем запустите ваш xsl:for-each на наборе узлов в этой новой переменной.Тогда отношение предшествующего брата и сестры будет отражать отсортированный порядок.

1 голос
/ 12 мая 2011

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

Итак, вы сказали, как вы хотите решить свою проблему, и она не будет работать.Следующий шаг - рассказать нам, в чем проблема.

0 голосов
/ 13 мая 2011

Поскольку XSLT гарантирует, что элементы с одинаковыми ключами сортировки будут отображаться в порядке документа, вы можете заменить

<xsl:when test="preceding-sibling::data[1]/type != type">

на

<xsl:when test="not(preceding::data/type = type)">

, чтобы проверить, является ли текущий узел первым узломв документе (и, следовательно, в отсортированном наборе) с его типом.(Обратите внимание, что я использую preceding вместо preceding-sibling, поскольку я не знаю, будут ли все ваши элементы данных братьями и сестрами в исходном документе.)

Если производительность является проблемой, вы также можете использоватьxsl:key.Другое решение - группировка (с использованием мюнхенской группировки в XSLT 1.0 и xsl:for-each-group в XSLT 2.0).

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