2012-10-01 39 views
3

我想在XSLT 2.0中使用xsl:for-each對元素進行分組。XSLT 2.0使用<xsl:for-each-group>分組>

這是我輸入的說明:

<root> 
    <chapter> 
      <heading> heading text </heading> 
      <title> title </title> 
      <p> 1111 </p> 
      <p> 2222 </p> 
      <center> text </center> 
      <p> 3333 </p> 
      <title> another title </title> 
      <p> 4444 </p> 
      <center> text </center> 
      <p> 5555 </p> 
    </chapter> 
    <chapter> 
      <heading> heading text </heading> 
      <title> another title </title> 
      <p> 6666 </p> 
      <p> 7777 </p> 
      <title> another title </title> 
      <p> 8888 </p> 
      <p> 9999 </p> 
    </chapter> 
<root> 

我對每個<title>元素匹配和分組每個下面的元素,直到下一個<title>成元素<section>試圖組此文件。以下是我希望我的輸出看起來像:不工作

<root> 
    <chapter> 
      <heading> Heading text </heading> 
      <section> 
       <title> title </title> 
       <p> 1111 </p> 
       <p> 2222 </p> 
       <center> text </center> 
       <p> 3333 </p> 
      </section> 
      <section> 
       <title> title </title> 
       <p> 4444 </p> 
       <center> text </center> 
       <p> 5555 </p> 
      </section> 
      <section> 
       <title> title </title> 
       <p> 6666 </p> 
       <p> 7777 </p> 
       <center> text </center> 
       <p> 8888 </p> 
       <p> 9999 </p> 
      </section> 
    <chapter> 
<root> 

我現在的模板:

<xsl:template match="chapter"> 
    <chapter> 
     <xsl:for-each-group select="*" group-starting-with="title"> 
      <section> 
       <xsl:copy-of select="current-group()" /> 
      </section> 
     </xsl:for-each-group> 
    </chapter>    
</xsl:template> 

上面的樣式確實組不過我想要的部分但它也組,每組<heading>元素由於某種原因進入它自己的<section>。有什麼建議麼?

在此先感謝。

回答

3

你可能想

<xsl:copy-of select="current-group()" /> 

而非value-of。對於標題,如果你知道,每個章節將只有一個heading元素,那麼你可以說

<xsl:template match="chapter"> 
     <xsl:copy-of select="heading" /> 
     <xsl:for-each-group select="*[not(self::heading)]" group-starting-with="title"> 
      <section> 
       <xsl:copy-of select="current-group()" /> 
      </section> 
     </xsl:for-each-group>    
</xsl:template> 

即拔出單獨標題,然後從組元素將其排除,進行分組。

+0

我意識到我需要價值的發佈問題後不久,不過這得到了它。忘記自我軸!謝謝伊恩。 – Laterade

+0

或者確實是'',正如Sean所建議的那樣。我的大部分經驗是使用XSLT 1.0,並且我傾向於忘記2.0中的額外序列運算符。 –

4

我會用...

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

<xsl:template match="/*"> 
    <root> 
    <xsl:for-each-group select="chapter" group-by="heading"> 
     <chapter> 
     <xsl:copy-of select="current-group()[1]/heading" /> 
     <xsl:for-each-group select="current-group()/(* except heading)" 
          group-starting-with="title"> 
      <section> 
      <xsl:copy-of select="current-group()" /> 
      </section> 
     </xsl:for-each-group> 
     </chapter> 
    </xsl:for-each-group> 
    </root> 
</xsl:template> 

</xsl:stylesheet> 
4

我通常使用一個xsl:選擇在換各組的身體來區分確實開始與組羣開始-with元素從第一個「真正的羣體」之前的「領先臀部」。如果您知道「前導臀部」將僅包含標題元素,那麼您已獲得許多其他解決方案,可以很好地工作。另一種更普遍的解決方案(因爲它沒有什麼是在臀部假設),但沿着相同的路線,方法是:

<xsl:copy-of select="title[1]/preceding-sibling::*"> 
<xsl:for-each-group select="title[1]/(., following-sibling::*)"> 
    <section> 
    <xsl:copy-of select="current-group()"/> 
    </section> 
</xsl:for-each-group>