Разделить список узлов на части - PullRequest
2 голосов
/ 15 июня 2010

XML:

<mode>1</mode>
<mode>2</mode>
<mode>3</mode>
<mode>4</mode>
<mode>5</mode>
<mode>6</mode>
<mode>7</mode>
<mode>8</mode>
<mode>9</mode>
<mode>10</mode>
<mode>11</mode>
<mode>12</mode>

Мне нужно разделить его на части (например, на 4):

XSLT:

<xsl:variable name="vNodes" select="mode"/>
<xsl:variable name="vNumParts" select="4"/>
<xsl:variable name="vNumCols" select="ceiling(count($vNodes) div $vNumParts)"/>
<xsl:for-each select="$vNodes[position() mod $vNumCols = 1]">
    <xsl:variable name="vCurPos" select="(position()-1)*$vNumCols +1"/>
    <ul>
        <xsl:for-each select="$vNodes[position() >= $vCurPos and not(position() > $vCurPos + $vNumCols -1)]">
            <li><xsl:value-of select="."/></li>
        </xsl:for-each>
    </ul>
</xsl:for-each>

этот код написан Димитром Новатчевым - отличным кодером))

но для числа узлов меньше количества частей (например, у меня есть 2 modes), этот код не работает - он ничего не выводит.

Как его обновить для этого случая (без choose конструкции)?

Ответы [ 2 ]

2 голосов
/ 15 июня 2010

Хотя проблема неверно определена, если число узлов меньше количества деталей, здесь приведено преобразование, которое я думаю производит на выходе, который ОП, скорее всего, хочет (Почему он просто не указал это поведение ???):

<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="node()|@*">
   <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="/t">
  <t>
    <xsl:variable name="vNodes" select="mode"/>
    <xsl:variable name="vNumParts" select="4"/>
    <xsl:variable name="vNumCols" select="ceiling(count($vNodes) div $vNumParts)"/>

    <xsl:variable name="vrealNum">
      <xsl:choose>
        <xsl:when test="$vNumCols >1">
         <xsl:value-of select="$vNumCols"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="count($vNodes)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:for-each select="$vNodes[position() mod $vrealNum = 1]">
        <xsl:variable name="vCurPos" select="(position()-1)*$vrealNum +1"/>
        <ul>
            <xsl:for-each select="$vNodes[position() >= $vCurPos and not(position() > $vCurPos + $vrealNum -1)]">
                <li><xsl:value-of select="."/></li>
            </xsl:for-each>
        </ul>
    </xsl:for-each>
  </t>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к следующему XML-документу (он даже не может предоставить правильно сформированныйXML-документ!):

<t>
    <mode>1</mode>
    <mode>2</mode>
</t>

вывод - это то, что я догадываюсь ОП хотел ...

<t>
    <ul>
        <li>1</li>
        <li>2</li>
    </ul>
</t>
0 голосов
/ 15 июня 2010

но для количества узлов меньше, чем количество частей (например, у меня есть 2 режимы) этот код не работает - это ничего не выводит.

На самом деле код работает правильно .

Всякий раз, когда количество деталей превышает количество узлов, решение проблемы не существует: « Разделите 2 узла на 4 части равным числом » - единственное решение состоит в том, что каждая деталь содержит 0 узлов.

Теперь вы решаете новую, другую проблему, и неудивительно, что решение другой проблемы не работает для этой новой проблемы .

Способ состоит в том, чтобы правильно сформулировать новую проблему и задать ее. Тогда многие люди будут рады ответить.

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