У меня есть этот html
<h1>Index</h1> <p>some content</p> <p>some more content</p> <h1>Tema</h1> <p>some content</p> <p>other content</p> <h2>Sección</h2> <p>some content</p> <p>other content</p> <h2>Unidad</h2> <p>some content</p> <p>other content</p>
Используя это, я должен создать вложенное меню, подобное следующему (без комментариев, это просто должно быть объяснительным):
<div id="siteNav"> <ul> <li> <a href="index.html" class="daddy"> Index <!-- H1 --> </a></li> <li> <a href="tema.html" class="daddy"> Tema <!-- H1 --> </a> <ul> <li> <a href="seccion.html" class="daddy"> Sección <!-- H2 --> </a> <ul> <li id="active"> <a href="unidad.html" class="no-ch"> Unidad <!-- H3 --> </a> </li> </ul> </li> </ul> </li> </ul> </div>
Моим частичным решением было изменение html с PHP для группировки заголовков:
<div class='menu'> <h1>Index</h1> <p>some content</p> <p>some more content</p> </div> <div class='menu'> <h1>Tema</h1> <p>some content</p> <p>other content</p> <div class='menu2'> <h2> ... </h2> </div> </div>
Затем примените следующий шаблон xsl:
<xsl:template match="/"> <ul> <xsl:apply-templates/> </ul> </xsl:template> <xsl:template match="div[@class='menu']"> <li> <xsl:if test="count(div[@class='menu2']) > 0"> <xsl:attribute name='class'> daddy </xsl:attribute> <xsl:value-of select='h1' /> </xsl:if> <xsl:if test="count(div[@class='menu2']) > 0"> <ul class='other-section'><xsl:apply-templates select="div[@class='menu2']"/></ul> </xsl:if> </li> </xsl:template> <xsl:template match="div[@class='menu2']"> <li> <a> <xsl:attribute name='href'> <xsl:value-of select="concat(translate(h2, 'áéíóú ', 'aeiou-'),'.html')" /> </xsl:attribute> <xsl:value-of select='h2'/> </a> </li> </xsl:template>
Есть ли чистый способ XSLT 1.0 для этого?
Если – и только если – ваш входной HTML-документ также является хорошо сформированным XML-документом, например:
<html> <h1>Index</h1> <p>some content</p> <p>some more content</p> <h1>Tema</h1> <p>some content</p> <p>other content</p> <h2>Sección</h2> <p>some content</p> <p>other content</p> <h2>Unidad</h2> <p>some content</p> <p>other content</p> </html>
то вы можете использовать таблицу стилей, подобную этой:
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> <xsl:key name="h2" match="h2" use="generate-id(preceding-sibling::h1[1])" /> <xsl:template match="/html"> <div id="siteNav"> <ul> <xsl:apply-templates select="h1"/> </ul> </div> </xsl:template> <xsl:template match="h1 | h2"> <li> <a href="{.}.html" class="{local-name()}"> <xsl:value-of select="."/> </a> <xsl:variable name="h2" select="key('h2', generate-id())" /> <xsl:if test="$h2"> <ul> <xsl:apply-templates select="$h2"/> </ul> </xsl:if> </li> </xsl:template> </xsl:stylesheet>
для получения следующего результата :
<div id="siteNav"> <ul> <li> <a href="Index.html" class="h1">Index</a> </li> <li> <a href="Tema.html" class="h1">Tema</a> <ul> <li> <a href="Sección.html" class="h2">Sección</a> </li> <li> <a href="Unidad.html" class="h2">Unidad</a> </li> </ul> </li> </ul> </div>