2015-01-21 1 views
2

У меня есть список элементов:XSLT 1.0 группирования нескольких же узлов на одном уровне с различными значениями

<vehiciles> 
    <vehicile value="_CAR">CAR</vehicile> 
    <vehicile value="01">vehicile1</vehicile> 
    <vehicile value="02">vehicile2</vehicile> 
    <vehicile value="03">vehicile3</vehicile> 
    <vehicile value="_TRUCK">TRUCK</vehicile> 
    <vehicile value="04">vehicile4</vehicile> 
    <vehicile value="05">vehicile5</vehicile> 
    <vehicile value="06">vehicile6</vehicile> 
</vehiciles> 

К сожалению, я не могу изменить структуру, но я должен группе он (в HTML выбрать/OPTGROUP тег) по категориям обозначенный транспортным средством, значение которого начинается с подчеркивания.

Результат я хотел достичь:

<select> 
    <optgroup label="CAR"> 
    <option value="01">vehicile1</option> 
    <option value="02">vehicile2</option> 
    <option value="03">vehicile3</option> 
    </optgroup> 
    <opgroup label="TRUCK"> 
    <option value="04">vehicile4</option> 
    <option value="05">vehicile5</option> 
    <option value="06">vehicile6</option> 
    </optgroup> 
</select> 

Что я попытался было:

<xsl:template match="field" mode="dropdown_list"> 
    <select> 
    <xsl:choose> 
     <xsl:when test="vehiciles/vehicile[starts-with(@value, '_')]"> 
     <xsl:for-each select="vehiciles/vehicile[starts-with(@value, '_')]"> 
      <xsl:variable name="lastValue" select="following-sibling::*[starts-with(@value, '_')][@value]" /> 
      <optgroup> 
      <xsl:attribute name="label"> 
       <xsl:value-of select="text()"/> 
      </xsl:attribute> 

      <xsl:for-each select="following-sibling::*[not(preceding::vehicile[1][@value = $lastValue])]"> 
       <option value="{@value}"> 
       <xsl:value-of select="text()"/> 
       </option> 
      </xsl:for-each> 

      </optgroup> 
     </xsl:for-each> 

    </xsl:when> 
    <xsl:otherwise> 
     <!-- something here --> 
    </xsl:otherwise> 
    </xsl:choose> 
</select> 
</xsl:template> 

Это выход второй хороший цикл, но первый содержит все элементы. Попытка выяснить это в течение нескольких часов без везения.

Попытка сделать рекурсию, но не удалось, а также группировка Muenchian.

Есть ли способ поиска с определенного узла до первого родного брата, который соответствует критериям? Или по-другому?

Любая помощь приветствуется.

ответ

1

Попробуй так:

XSLT 1.0

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

<xsl:key name="vehicile" match="vehicile[not(starts-with(@value, '_'))]" use="generate-id(preceding-sibling::vehicile[starts-with(@value, '_')][1])" /> 

<xsl:template match="/vehiciles"> 
    <select> 
     <xsl:for-each select="vehicile[starts-with(@value, '_')]"> 
      <optgroup label="{substring-after(@value, '_')}"> 
       <xsl:for-each select="key('vehicile', generate-id())"> 
        <option value="{@value}"> 
         <xsl:value-of select="."/> 
        </option> 
       </xsl:for-each> 
      </optgroup> 
     </xsl:for-each> 
    </select> 
</xsl:template> 

</xsl:stylesheet> 
+0

Работаю как шарм! Благодаря! –

1

Использование

<xsl:template match="vehiciles"> 
    <select> 
    <xsl:apply-templates select="vehicile[starts-with(@value, '_')]"/> 
    </select> 
</xsl:template> 

<xsl:template match="vehicile[starts-with(@value, '_')]"> 
    <optgroup label="{substring(@value, 2)}"> 
    <xsl:apply-templates select="key('k1', generate-id())"/> 
    </optgroup> 
</xsl:template> 

<xsl:key name="k1" match="vehicile[not(starts-with(@value, '_'))]" 
    use="generate-id(preceding-sibling::vehicile[starts-with(@value, '_')][1])"/> 

<xsl:template match="vehicile[not(starts-with(@value, '_'))]"> 
    <xsl:variable name="num"> 
    <xsl:number count="vehicile[not(starts-with(@value, '_'))]"/> 
    </xsl:variable> 
    <option value="{format-number($num, '00')}"><xsl:value-of select="."/></option> 
</xsl:template> 

http://xsltransform.net/jyH9rMi см для полного примера.

+0

Спасибо за помощь. Хотя решение @michael было более сжатым. –

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