2014-12-09 6 views
0

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

<Root> 
    <Child No="1" Month="0" Date="13/08/2014" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="2" Month="1" Date="13/09/2014" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="3" Month="2" Date="13/10/2014" Payment="200"> 
     <Totals/> 
    </Child> 
    <Child No="4" Month="3" Date="13/11/2014" Payment="300"> 
     <Totals/> 
    </Child> 
    <Child No="5" Month="4" Date="13/12/2014" Payment="300"> 
     <Totals/> 
    </Child> 
    <Child No="6" Month="5" Date="13/01/2015" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="7" Month="6" Date="13/01/2015" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="8" Month="7" Date="13/01/2015" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="9" Month="8" Date="13/01/2015" Payment="100"> 
     <Totals/> 
    </Child> 
    <Child No="10" Month="9" Date="13/01/2015" Payment="100"> 
     <Totals/> 
    </Child> 
</Root> 

Мне нужно создать новый узел PP, когда Child[n]/Payment <> Child[n-1]/Payment с использованием XSLT.

И я ожидаю ниже результата,

<PPS> 
    <PP> 
     <Ps> 
      <StartMonth>0</StartMonth> 
      <EndMonth>1</EndMonth> 
      <P> 
       <Amount>100</Amount> 
       <startP>1</startP> 
      </P> 
      <P> 
       <Amount>100</Amount> 
       <startP>2</startP> 
      </P> 
     </Ps> 
    </PP> 
    <PP> 
     <Ps> 
      <StartMonth>2</StartMonth> 
      <EndMonth>2</EndMonth> 
      <P> 
       <Amount>200</Amount> 
       <startP>3</startP> 
      </P> 
     </Ps> 
    </PP> 
    <PP> 
     <Ps> 
      <StartMonth>3</StartMonth> 
      <EndMonth>4</EndMonth> 
      <P> 
       <Amount>300</Amount> 
       <startP>4</startP> 
      </P> 
      <P> 
       <Amount>300</Amount> 
       <startP>5</startP> 
      </P> 
     </Ps> 
    </PP> 
    <PP> 
     <Ps> 
      <StartMonth>5</StartMonth> 
      <EndMonth>9</EndMonth> 
      <P> 
       <Amount>100</Amount> 
       <startP>6</startP> 
      </P> 
      <P> 
       <Amount>100</Amount> 
       <startP>7</startP> 
      </P> 
      <P> 
       <Amount>100</Amount> 
       <startP>8</startP> 
      </P> 
      <P> 
       <Amount>100</Amount> 
       <startP>9</startP> 
      </P> 
      <P> 
       <Amount>100</Amount> 
       <startP>10</startP> 
      </P> 
     </Ps> 
    </PP> 
</PPS> 

Вот мой пример XSLT

<xsl:stylesheet version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:key name="x" match="Child" use="@Payment"/> 
    <xsl:template match="/Root"> 
     <PPS> 
      <xsl:for-each select="CF"> 
       <xsl:if test="generate-id(.) = generate-id(key('x',@Payment)[1])"> 
        <PP>       
         <Ps> 
          <xsl:for-each select="key('x', @Payment)"> 
           <P> 
           <Amount><xsl:value-of select="format-number(translate(@Payment, ',','.'),'0.00')"/></Amount> 
           <startP><xsl:value-of select="@Date"/></startP> 
           </P> 
          </xsl:for-each> 
         </Ps> 
        </PP> 
       </xsl:if> 
      </xsl:for-each> 
     </PPS> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Вы пробовали что-нибудь? Можете ли вы разместить свой XSLT? –

+0

А какая версия XSLT вы используете? 1,0, 2,0? –

+0

Я использую XSLT V1.0. –

ответ

0

Это будет работать:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/Root"> 
    <PPS> 
     <xsl:for-each select="Child"> 
      <xsl:variable name="Payment" select="@Payment"/> 
      <xsl:if test="not(preceding::*[1][self::Child and @Payment = $Payment])"> 
       <PPS> 
        <Ps> 
         <xsl:apply-templates select="current()"/> 
         <xsl:apply-templates select="following::*[1][self::Child and @Payment = $Payment]"> 
          <xsl:with-param name="Payment" select="$Payment"/> 
         </xsl:apply-templates> 
        </Ps> 
       </PPS> 
      </xsl:if> 
     </xsl:for-each> 
    </PPS> 
</xsl:template> 
<xsl:template match="Child"> 
    <xsl:param name="Payment"/> 
    <P> 
     <Amount> 
      <xsl:value-of select="@Payment"/> 
     </Amount> 
     <startP> 
      <xsl:value-of select="@No"/> 
     </startP> 
    </P> 
    <xsl:apply-templates select="following::*[1][self::Child and @Payment = $Payment]"/> 
</xsl:template> 
</xsl:stylesheet> 
+0

Большое спасибо за быстрое решение. Это отлично работает для меня. Вы сохранили мое время ........... –

+0

Было бы очень легко, если бы вы использовали XSLT2.0 –

+0

Hi Lingamurthy, я только что изменил свой XML-запрос запроса и ответа. Не могли бы вы помочь мне включить их в XSLT. Спасибо заранее. –

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