2010-01-27 5 views
3

Я whant в цикле через XML-файла то будет выглядеть следующим образом:XSL - цикл по подразделам узлов в XML

<node> 
    <cd name="td1"> 
    <data value="cd1-0" /> 
    <cd name="td2"> 
     <data value="cd1-1" /> 
    </cd> 
    <cd name="td3"> 
     <data value="cd1-2" /> 
    </cd> 
    </cd> 
    <cd name="td4"> 
    <data value="cd2-0" /> 
    </cd> 
</node> 

Это результат, что я, что это.

<html> 
    <table border="1"> 
    <tr> 
     <td>cd1-0</td> 
     <td></td> 
    </tr> 
    <tr> 
     <td></td> 
     <td>cd1-1</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td>cd1-2</td> 
    </tr> 
    <tr> 
     <td>cd2-0</td> 
     <td></td> 
    </tr> 
    </table> 
</html> 

В этом нелогич- У меня 2 уровней на узле cd. Но уровень может быть бесконечным. Поэтому мне нужна какая-то рекурсивная функция цикла.

+0

hhhhhhhhomework! :) – Younes

+0

Подсказки: template match = "node/cd" – Tommy

ответ

0

XML, который вы отправили, не похож на хорошо сформированный XML. Оставив это, вы можете использовать элемент foreach в xslt.

например:

<table> 
<xsl:for-each select="node/cd"> 
<tr> 
<td> 
<xsl:value-of select="data/@value"/> 
</td> 
</tr> 
</xsl:for-each> 
</table> 

Проверить эту ссылку для более: http://www.w3schools.com/Xsl/xsl_for_each.asp

Надеется, что вы получили эту идею.

Обновление: Благодаря субтененте для очистки xml. Вы можете использовать шаблон для решения этой проблемы

<xsl:template match="node"> 
<html> 
    <body> 
    <table border="1"> 
     <xsl:apply-templates select="cd" /> 
    </table> 
    </body> 
</html> 
</xsl:template> 

<xsl:template match="cd"> 
<tr> 
    <td> 
    <xsl:value-of select="@name" /> 
    </td> 
    <td> 
    <xsl:value-of select="data/@value"/> 
    </td> 
</tr> 

<xsl:if test="cd"> 
    <xsl:apply-templates select="cd" /> 
</xsl:if> 
</xsl:template> 

Это будет производить в следующей таблице:

<table border="1"> 
<tbody> 
<tr> 
<td>td1</td> 
<td>cd1-0</td> 
</tr> 
<tr> 
<td>td2</td> 
<td>cd1-1</td> 
</tr> 
<tr> 
<td>td3</td> 
<td>cd1-2</td> 
</tr> 
<tr> 
<td>td4</td> 
<td>cd2-0</td> 
</tr> 
</tbody></table> 

Предоставленный XSLT должен быть изменен немного, чтобы достичь именно то, что вы хотите. Если с тобой все в порядке. Отлично.

Источник: 1

Ramjee

+0

Вам не нужен тест 'xsl: if' в конце. '' будет делать только что-либо, если есть один или несколько дочерних элементов 'cd'; проверка того, есть ли одна из них, является избыточной. –

+0

Спасибо, Роберт, согласился. – rAm

0

Один из способов сделать это:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <!-- adapt output method and doctype to your needs --> 
    <xsl:output 
    method="html" 
    doctype-system="http://www.w3.org/TR/html4/strict.dtd" 
    doctype-public="-//W3C//DTD HTML 4.01//EN" 
    indent="yes" 
    /> 

    <!-- the document root becomes html --> 
    <xsl:template match="/"> 
    <html> 
     <xsl:apply-templates select="*" /> 
    </html> 
    </xsl:template> 

    <!-- node becomes table --> 
    <xsl:template match="node"> 
    <table border="1"> 
     <xsl:apply-templates select="*" /> 
    </table> 
    </xsl:template> 

    <!-- 1st level cd elements (children of node) go into first td --> 
    <xsl:template match="node/cd"> 
    <tr> 
     <td><xsl:value-of select="data/@value" /></td> 
     <td /> 
    </tr> 
    </xsl:template> 

    <!-- 2nd level cd elements (children of cd) go into second td --> 
    <xsl:template match="cd/cd"> 
    <tr> 
     <td /> 
     <td><xsl:value-of select="data/@value" /></td> 
    </tr> 
    </xsl:template> 

</xsl:stylesheet> 
2

Это будет работать с любым уровнем внахлестку cd элементов.

Чтобы создать структуру <html><head/><body>...</body>), это может быть шаблон match='node'.

Он пропустит пустой трейлинг <td/>, который не требуется для рендеринга.

XSL

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 

    <xsl:template match="node"> 
     <xsl:element name="table"> 
     <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="cd"> 
     <xsl:element name="tr"> 
      <xsl:for-each select="ancestor::cd"> 
       <xsl:element name="td"/> 
      </xsl:for-each> 
      <xsl:element name="td"> 
       <xsl:value-of select="./data/@value" /> 
      </xsl:element> 
     </xsl:element> 
     <xsl:apply-templates /> 
    </xsl:template> 

</xsl:stylesheet> 

Выход

<table> 
    <tr><td>cd1-0</td></tr>  <!-- Here the second <td/> is skipped --> 
    <tr><td/><td>cd1-1</td></tr> 
    <tr><td/><td>cd1-2</td></tr> 
    <tr><td>cd2-0</td></tr>  <!-- Here the second <td/> is skipped --> 
</table> 
Смежные вопросы