2014-09-06 81 views
1

我正在創建XSLT文件,並將XML文件中的一些數據顯示爲CSV。 我被困在一個特定的方面,因爲我無法找到許多類似xml結構的在線示例。在xslt中分組多個相同的節點內容

鑑於這種假設的XML:

<collection> 
<book> 
    <author> author1name </author> 
    <author> author2name </author> 
    <title> booktitle </title> 
</book> 
<book> 
    <author> authorname </author> 
    <title> booktitle </title> 
</book> 
</collection> 

而XSLT:

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

<xsl:template match="/"> 
author,title 

<xsl:for-each select="//book"> 
<xsl:value-of select="concat 

(author,',',title',','&#xA;')"/> 
</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 

其中給出的

author, title 
author1name, booktitle 
authorname, booktitle 

注意的輸出,有包括在輸出沒有author2。這是數據的一大損失。 我試圖使用嵌套for循環來循環所有作者,但我已經打了太多的錯誤來計數。

有人建議可以產生的

author1name;author2name, booktitle 

輸出爲一個書的方法? (兩位作者用分號分隔)

感謝您的幫助。

回答

0

CONCAT()是字符串函數;您不能將它應用於節點集。嘗試改爲:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="UTF-8"/> 

<xsl:template match="/"> 
    <xsl:text>author,title&#10;</xsl:text> 
    <xsl:for-each select="collection/book"> 
     <xsl:for-each select="author"> 
      <xsl:value-of select="."/> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>;</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="title"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 
2

你可以做的是建立一個滿足author模板,你只需輸出的名稱,分號之前,如果它不是第一作者

<xsl:template match="author"> 
    <xsl:if test="position() > 1">;</xsl:if> 
    <xsl:value-of select="." /> 
</xsl:template> 

然後,輸出每本書,而不是把author在CONCAT語句,使用xsl:apply-templates代替

<xsl:apply-templates select="author" /> 
<xsl:value-of select="concat(',', title,'&#xA;')"/> 

試試這個XSLT

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

    <xsl:template match="collection"> 
     <xsl:text>author,title</xsl:text> 
     <xsl:value-of select="'&#xA;'" /> 
     <xsl:apply-templates select="book"/> 
    </xsl:template> 

    <xsl:template match="book"> 
     <xsl:apply-templates select="author"/> 
     <xsl:value-of select="concat(',', title,'&#xA;')"/> 
    </xsl:template> 

    <xsl:template match="author"> 
     <xsl:if test="position() &gt; 1">;</xsl:if> 
     <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

編輯:順便說一句,在未來,如果你能使用XSLT 2.0,你可以利用xsl:value-of運營商的separator屬性來達到相同的結果:

<xsl:value-of select="author" separator=";" />