2010-06-15 2 views
2

XML: (. Для бывших 4)список Сплит узел в части

<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> 

мне нужно разделить его на части:

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> 

этот код написан Dimitre Novatchev - отличный кодер))

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

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

ответ

2

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

<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

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

На самом деле, код верно работает.

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

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

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

+0

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

+1

@ Kalinin: Не ожидайте удовлетворительного решения, если вы не объясните, что значит разделить две вещи на четыре части. –

+0

Вы правы. это моя ошибка. я извиняюсь. – Kalinin

Смежные вопросы