2016-03-21 4 views
1

Я борюсь с XSLT в течение нескольких часов, и я пришел в StackOverflow для получения справки. У меня есть некоторые ввода текста, как это:Группировка некоторых элементов XML с помощью XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<div> 
<p class="text">Some regular text</p> 
<p class="first">The first part</p> 
<p class="next">and then some text</p> 
<p class="next">and some more</p> 

<p class="regular">Some regular text</p> 
<p class="text1">Some regular text</p> 
<p class="text2">Some regular text</p> 
<p class="first">Here some new text</p> 
<p class="next">and some more</p> 
<p class="next">and the end of this section</p> 
<p class="text3">Some regular text</p> 
</div> 

Я хотел бы закончить с этим

<?xml version="1.0" encoding="UTF-8"?> 
<div> 
<p>Some regular text</p> 

<group> 
    <p>The first part</p> 
    <p>and then some text</p> 
    <p>and some more</p> 
</group> 

<p>Some regular text</p> 
<p>Some regular text</p> 
<p>Some regular text</p> 

<group> 
    <p>Here some new text</p> 
    <p>and some more</p> 
    <p>and the end of this section</p> 
</group> 

<p>Some regular text</p> 
</div> 

Я знаю, что это не удивительно трудно, но я не понимаю ... The XSLT у меня прямо сейчас:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
exclude-result-prefixes="xs" 
version="2.0"> 
<xsl:template match="/"> 
    <xsl:apply-templates select="*" /> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:copy> 
     <xsl:for-each select="@*"> 
      <xsl:copy /> 
     </xsl:for-each> 
     <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="div"> 
    <lg> 
     <xsl:apply-templates/> 
    </lg> 
</xsl:template> 


<xsl:template match="/div"> 
    <xsl:for-each-group select="//p[@class='first']/following-sibling::p[@class='next']" group-by="text()"> 
     <group> 
      <xsl:apply-templates/> 
     </group> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 

это не работает вообще :(Я был бы очень признателен, если кто-то может мне помочь, потому что у меня действительно есть проблемы с пониманием того, как работает XSLT ...

С наилучшими пожеланиями, Хосе

ответ

2

Вы пытаетесь группе p, которые имеют атрибут class установлен на «первый», а затем все «рядом» из них.

Для вашего данного XML, XSLT это может сделать трюк:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output method="xml" indent="yes" /> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
</xsl:template> 

    <xsl:template match="/div"> 
    <xsl:for-each-group select="p" group-adjacent="@class = 'first' or @class='next'"> 
     <xsl:choose> 
      <xsl:when test="@class = 'first' or @class='next'"> 
       <group> 
        <xsl:apply-templates select="current-group()" /> 
       </group> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:apply-templates select="current-group()" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each-group> 
</xsl:template> 

<xsl:template match="@class" /> 
</xsl:stylesheet> 

Однако, это не будет работать в этом случае, как было бы поместить все p элементы в одной группе.

<div> 
<p class="first">The first part</p> 
<p class="next">and then some text</p> 
<p class="first">Here some new text</p> 
<p class="next">and some more</p> 
</div> 

Если это не то, что вы хотите, попробуйте этот XSLT вместо

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output method="xml" indent="yes" /> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
</xsl:template> 

    <xsl:template match="/div"> 
    <xsl:for-each-group select="p" group-starting-with="p[@class='first']"> 
     <xsl:for-each-group select="current-group()" group-adjacent="@class='first' or @class='next'"> 
     <xsl:choose> 
      <xsl:when test="@class='first' or @class='next'"> 
       <group> 
        <xsl:apply-templates select="current-group()" /> 
       </group> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:apply-templates select="current-group()" /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:for-each-group> 
</xsl:template> 

<xsl:template match="@class" /> 
</xsl:stylesheet> 
+0

Привет Тим, спасибо за ответ !! Насколько я понимаю, вы выбираете это p, определяя их отрицательным образом: те p, которые не имеют никакого класса. Можем ли мы попробовать это положительно? Итак, выберите этот элемент с этим конкретным классом? Я попытался, если бы это вызвало удивление, это не сработало –

+0

Я отредактировал вход xml, чтобы лучше его покрыть –

+1

Я обновил свой ответ двумя возможными XSLT, которые вы можете попробовать. –

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