2016-12-29 4 views
0

Это HTML:XSLT: повторить один узел с каждым последовательным узлом

<html> 
    <div> 
     <div class="theheader">The first header</div> 
    </div> 
    <div class="thecontent"> 
     <div class="col1">Col 1 </div> 
     <div class="col2">Col 2 </div> 
    </div> 
    <div class="thecontent"> 
     <div class="col1">Col 3 </div> 
     <div class="col2">col 4 </div> 
    </div> 
    <div> 
     <div class="theheader">The second header</div> 
    </div> 
    <div class="thecontent"> 
     <div class="col1">Col 5 </div> 
     <div class="col2">Col 6 </div> 
    </div> 
    <div class="thecontent"> 
     <div class="col1">Col 7 </div> 
     <div class="col2">Col 8 </div> 
    </div> 
</html> 

Это XSL:

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

    <xsl:template match="div[@class='theheader']" /> 

    <xsl:template match="div[@class='thecontent']"> 
     <xsl:value-of select="//div[@class='theheader']" /><xsl:text>: </xsl:text> 
     <xsl:value-of select="." /> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

Это выход:

The first header: Col 1 Col 2 
The first header: Col 3 col 4 
The first header: Col 5 Col 6 
The first header: Col 7 Col 8 

Желаемый выход :

The first header: Col 1 Col 2 
The first header: Col 3 col 4 
The second header: Col 5 Col 6 
The second header: Col 7 Col 8 

Как это можно сделать? XSLT 1.0 предпочтительнее.

Также пробовал:

<xsl:value-of select=".//div[@class='theheader']" /><xsl:text>: </xsl:text> 

(точка перед тем //) и не заголовок не выводится. Может ли кто-нибудь сказать мне, почему? Отредактированы примеры, потому что первое издание было слишком упрощено. Теперь SO говорит мне, что это слишком много кода. Надеюсь, что этот излишний текст поможет.

ответ

3

Вам нужно будет переместить код для вывода заголовка из шаблона, соответствующего «theheader», вместо этого в шаблон, соответствующий «thecontent», чтобы он повторялся. Вам также нужно будет использовать ось preceding-sibling, чтобы получить необходимый вам div.

Попробуйте этот XSLT

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

    <xsl:template match="div[@class='theheader']" /> 

    <xsl:template match="div[@class='thecontent']"> 
     <xsl:value-of select="preceding-sibling::div[div/@class='theheader'][1]/div" /><xsl:text>: </xsl:text> 
     <xsl:for-each select="div"> 
      <xsl:value-of select="." /> 
     </xsl:for-each> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

EDIT: В ответ на ваш комментарий о theheader потенциально быть более глубоких уровней, попробуйте один из этих выражений вместо

<xsl:value-of select="preceding-sibling::div[descendant::div/@class='theheader'][1]//div[@class='theheader']" /> 

<xsl:value-of select="preceding::div[@class='theheader'][1]" /> 
+0

Спасибо. Это сработало, но я упростил мой пример. Теперь переписано. Надеюсь, вы сможете посмотреть новое издание. – Peter

+0

@Peter: Как вы хотите, чтобы XSLT вел себя, если есть заголовки, но нет содержимого? Просто проверяя ваши требования к краевым делам ... – JohnLBevan

+0

Хорошее наблюдение Джон. Контент гарантирован. – Peter