2009-06-03 108 views
0

給定一個源文檔,像這樣:將一系列元素轉換爲單個列表的XSLT?

<A> 
    <B> 
    <C>item1</C> 
    </B> 
    <B> 
    <C>item2</C> 
    </B> 
    <B> 
    <C>item3</C> 
    </B> 
</A> 

,我可以使用的產品是這樣的什麼XSLT:

<A> 
    <B> 
    <C>item1</C> 
    <C>item2</C> 
    <C>item3</C> 
    </B> 
</A> 

我已經嘗試了片材...

<xsl:template match="B"> 
    <xsl:choose> 
     <xsl:when test="count(preceding-sibling::B)=0"> 
     <B> 
      <xsl:apply-templates select="./C"/> 
      <xsl:apply-templates select="following-sibling::B"/> 
     </B> 
     </xsl:when> 

     <xsl:otherwise> 
      <xsl:apply-templates select="./C"/> 
     </xsl:otherwise> 

    </xsl:choose> 
    </xsl:template> 

但我越來越...

<A> 
    <B> 
    <C>item1</C> 
    <C>item2</C> 
    <C>item3</C> 
    </B> 
    <C>item2</C> 
    <C>item3</C> 
</A> 

第二個問題:我很難調試XSLT。提示?

回答

3

最簡單的方法:

<xsl:template match="/A"> 
    <A> 
    <B> 
     <xsl:copy-of select=".//C" /> 
    </B> 
    </A> 
</xsl:template> 

要回答爲什麼你看到你與你的XSLT看到輸出的問題:

我aussume你有一個

<xsl:apply-templates select="B" /> 
到位

。這意味着:

  • <xsl:template match="B">被稱爲三次,每個<B>一次。
  • 對於第一<B>,它你打算怎樣,其他時間分支右轉入<xsl:otherwise>,通過你可能有<xsl:template match="C">複製<C>秒。這是您的額外<C>來自哪裏。
  • 要修復它(不,我贊同你的做法),你應該改變它像...

...這樣的:

<xsl:apply-templates select="B[1]" /> 
+0

嘿,我這裏有一個額外的模板......在上一篇文章中,你有一個:D – 2009-06-03 11:16:44

2

您可以使用Altova的XMLSPY或Visual Studio的調試。以下xslt會給出所需的o/p。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="A"> 
     <A> 
      <B> 
       <xsl:apply-templates/> 
      </B> 
     </A> 
    </xsl:template> 
    <xsl:template match="B"> 
     <xsl:copy-of select="C"/> 
    </xsl:template> 
</xsl:stylesheet> 

如果上述SOLN不適合你(我懷疑你是在處理一個更復雜的XML),你可能想貼在你的XML一些更多的信息。

此外,如果需要,具有B和C的模板可以進一步擴展模板o/p。

1

要回答你的第二個問題,我使用VS 2008 debugger,它的作用就像一個魅力。

1

此樣式表合併了兄弟<B>元素,而不管樣式表中的位置或其他元素名稱是什麼。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- By default, copy all nodes unchanged --> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Only copy the first B element --> 
    <xsl:template match="B[1]"> 
    <xsl:copy> 
     <!-- Merge the attributes and content of all sibling B elements --> 
     <xsl:apply-templates select="../B/@* | 
            ../B/node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Don't copy the rest of the B elements --> 
    <xsl:template match="B"/> 

</xsl:stylesheet> 

UPDATE:

如果你想成爲漂亮的打印結果,如果只有空白文本節點的輸入文檔中是微不足道的,那麼你可以添加到您的樣式表的頂部(作爲<xsl:stylesheet>的子女):

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/>