2014-04-14 49 views
1

我有一個電影的XML文件,其中的兩個例子如下所示 - mediaList中有很多電影元素,我希望我的XSLT將其轉換爲HTML表格供其他人查看。XSLT到html表

<mediaList> 
<movie id="1299349" dateCreated="2014-04-11" lastModified="2014-04-12"> 
    <title> 
     <titleSort>Armageddon</titleSort> 
    </title> 
    <director> 
     <personTerm type="code" authority="lccn">no98124072</personTerm> 
     <personTerm type="text">Bay, Michael, 1964-</personTerm> 
    </director> 
    <genre>Action and adventure</genre> 
    <genre>Disaster</genre> 
    <writer> 
     <personTerm type="code" authority="lccn">n91119795</personTerm> 
     <personTerm type="text">Hensleigh, Jonathan</personTerm> 
    </writer> 
    <writer> 
     <personTerm type="code" authority="lccn">no98124254</personTerm> 
     <personTerm type="text">Abrams, J. J. (Jeffrey Jacob), 1966-</personTerm> 
    </writer> 
    <screenplay href="http://endeavor.flo.org/vwebv/holdingsInfo?bibId=578717">PN1997 .A73 1997a</screenplay> 
    <language> 
     <languageTerm type="code" authority="iso639-2">eng</languageTerm> 
     <languageTerm type="text">English</languageTerm> 
    </language> 
    <year>1998</year> 
    <callNumber href="http://endeavor.flo.org/vwebv/holdingsInfo?bibId=1299349">[DVD] PN1995.9 .A3 B39 1999</callNumber> 
</movie> 
<movie id="1324917" dateCreated="2014-04-13"> 
    <title> 
     <titleSort>Police Story 2</titleSort> 
    </title> 
    <director> 
     <personTerm type="code" authority="lccn">no96039667</personTerm> 
     <personTerm type="text">Cheng, Long, 1954-</personTerm> 
    </director> 
    <genre>Martial arts</genre> 
    <genre>Buddy</genre> 
    <writer> 
     <personTerm type="code" authority="lccn">no96039667</personTerm> 
     <personTerm type="text">Cheng, Long, 1954-</personTerm> 
    </writer> 
    <writer> 
     <personTerm type="code" authority="lccn">no2005066079</personTerm> 
     <personTerm type="text">Tang, Edward, 1946-</personTerm> 
    </writer> 
    <language> 
     <languageTerm type="code" authority="iso639-3">yue</languageTerm> 
     <languageTerm type="text">Yue Chinese</languageTerm> 
    </language> 
    <year>1988</year> 
    <callNumber href="http://endeavor.flo.org/vwebv/holdingsInfo?bibId=1324917">[DVD] PN1995.9 .A3 C52 2006</callNumber> 
</movie> 
</Medialist 

現在,我的XSLT是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="html"/> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <link rel="stylesheet" type="text/css" href="mediaList.css"/> 
       <title/> 
      </head> 
      <body> 
       <table> 

        <tr> 
         <th>Title</th> 
         <th>Director</th> 
         <th>Genre</th> 
         <th>Writer</th> 
         <th>Screenplay</th> 
         <th>Source</th> 
         <th>Language</th> 
         <th>Year</th> 
         <th>Call Number</th> 
        </tr> 

        <xsl:for-each select="mediaList/movie"> 
         <tr> 
          <td> 
           <xsl:apply-templates select="./title"/> 
          </td> 
          <td> 
           <xsl:apply-templates select="./director/personTerm[@type='text']"/> 
          </td> 
          <xsl:choose> 
           <xsl:when test="count(./genre) > 1"> 
            <td> 
             <xsl:call-template name="recursiveGenre"> 
              <xsl:with-param name="numberG" select="count(./genre)"/> 
             </xsl:call-template> 
             <xsl:value-of select="./genre[1]"/> 
            </td> 
           </xsl:when> 
           <xsl:otherwise> 
            <td> 
             <xsl:value-of select="./genre"/> 
            </td> 
           </xsl:otherwise> 
          </xsl:choose> 

          <xsl:choose> 
           <xsl:when test="count(./writer) > 1"> 
            <td> 
             <xsl:call-template name="recursive"> 
              <xsl:with-param name="number" select="count(./writer)"/> 
             </xsl:call-template> 
             <xsl:value-of select="writer[1]/personTerm[@type='text']"/> 
            </td> 
           </xsl:when> 
           <xsl:otherwise> 
            <td> 
             <xsl:value-of select="writer/personTerm[@type='text']"/> 
            </td> 
           </xsl:otherwise> 
          </xsl:choose> 

          <td> 
           <xsl:apply-templates select="screenplay"/> 
          </td> 
          <td> 
           <xsl:apply-templates select="source"/> 
          </td> 
          <td> 
           <xsl:value-of select="./language/languageTerm[@type='text']"/> 
          </td> 
          <td> 
           <xsl:value-of select="./year"/> 
          </td> 
          <td> 
           <xsl:apply-templates select="callNumber"/> 
          </td> 
         </tr> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="title"> 
     <xsl:if test="./nonSort"> 
      <xsl:value-of select="./nonSort"/> 
      <xsl:text> </xsl:text> 
     </xsl:if> 
     <xsl:value-of select="./titleSort"/> 
    </xsl:template> 

    <xsl:template name="recursive"> 
     <xsl:param name="number"/> 
     <xsl:if test="$number > 1"> 
      <xsl:value-of select="writer[$number]/personTerm[@type='text']"/> 
      <xsl:text>/</xsl:text> 
      <xsl:call-template name="recursive"> 
       <xsl:with-param name="number" select="$number - 1"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template name="recursiveGenre"> 
     <xsl:param name="numberG"/> 
     <xsl:if test="$numberG > 1"> 
      <xsl:value-of select="genre[$numberG]"/> 
      <xsl:text>/</xsl:text> 
      <xsl:call-template name="recursiveGenre"> 
       <xsl:with-param name="numberG" select="$numberG - 1"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="screenplay | source | callNumber"> 
     <a> 
      <xsl:attribute name="href"> 
       <xsl:value-of select="./@href"/> 
      </xsl:attribute> 
      <xsl:value-of select="."/> 
     </a> 
    </xsl:template> 

</xsl:stylesheet> 

因此,雖然這個人是有點笨重,它的工作好了 - 它產生的標題錨定一個不錯的表格,並提供相關信息每個標題在後續單元格中。

但我真正想做的是以不同的方式顯示數據。如果,例如我想組按流派的標題,使輸出應該是這樣的:

 <table> 

        <tr> 
         <th>Genre</th> 
         <th>Title</th> 
         <th>Director</th> 
         <th>Writer</th> 
         <th>Screenplay</th> 
         <th>Source</th> 
         <th>Language</th> 
         <th>Year</th> 
         <th>Call Number</th> 
        </tr> 
    <tr><td>Action and Adventure</td> 
<td>Some Action/Comedy Title</td> 
... 
</tr> 
<tr><td>Action and Adventure</td> 
<td>Some Action/Comedy Title - The Return</td> 
... 
</tr> 
<tr><td>Action and Adventure</td> 
<td>Revenge of the Action/Comedy Title</td> 
... 
</tr> 
<tr><td>Comedy</td> 
<td>Some Action/Comedy Title</td> 
... 
<tr><td>Comedy</td> 
<td>Some Action/Comedy Title - The Return</td> 
</tr> 
<tr><td>Comedy</td> 
<td>Revenge of the Action/Comedy Title</td> 
... 
</tr> 
</table> 

我還希望能夠通過任何其他的「重複值」欄進行查看, (許多電影元素有不止一種語言元素),作家(相同的交易)

有沒有什麼辦法通過在單個XSLT文件中包含所有類型的轉換來重新生成表格?我需要爲每個「類型」表單獨使用XSLT文件嗎?有沒有更好的方法來做我在做的事情?

任何和所有的意見,將不勝感激 - 我仍然在這個相當新,我在我的第一個編程類和我們正在做的XML/XSLT。

+0

你好,我剛纔看到它是XSL 2.0。我到目前爲止只使用1.0版本 - 抱歉,我無法真正幫助分組。請嘗試使用而不是(http://stackoverflow.com/questions/6342902/for-loops-vs-apply-templates)。用於將搜索分組到板上。在XSLT 1.0中有Muenchian分組 - 我認爲在XSLT 2.0中有一個更簡單的解決方案。最好的問候,彼得 – Peter

回答

1

,我要在這裏給一個XSLT 1.0解決方案(這仍然會在XSLT 2.0工作)的解決方案是很普通的,簡單的添加新的分組參數。

在XSLT 1.0,您使用一種稱爲Muenchian Grouping做分組技術,包括創建鍵查找節點。對於「流派」,你可以定義像這樣的關鍵:

<xsl:key name="genre" match="genre" use="." /> 

而對於語言,你可以這樣做

<xsl:key name="language" match="language" use="languageTerm[@type='text']" /> 

然而,在這種特定情況下,它會更容易,如果的名字關鍵正是元素名稱匹配,並且「使用」屬性就是「」,所以對於這個回答鍵會像這樣

<xsl:key name="languageTerm" match="languageTerm[@type='text']" use="." /> 

對於你XSLT,您還需要定義一個參數上說來定義什麼你想要 組

<xsl:param name="groupBy" select="'genre'" /> 

這裏的值需要匹配鍵名(和被匹配元素的名稱)。

然後,以得到不同的值的每個組中,表達將是如下:

<xsl:apply-templates select="movie//*[local-name() = $groupBy] 
          [generate-id() = generate-id(key($groupBy, .)[1])]" /> 

(它是示出了分組子句第二個xpath條件)。

在以匹配該模板,這是有效的標題行,然後你可以得到所有電影元素「羣」,像這樣

<xsl:apply-templates select="key($groupBy, .)/ancestor::movie" /> 

以下是完整的XSLT在這case:

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

    <xsl:key name="genre" match="genre" use="." /> 
    <xsl:key name="languageTerm" match="languageTerm[@type='text']" use="." /> 

    <xsl:param name="groupBy" select="'genre'" /> 

    <xsl:template match="/*"> 
     <xsl:apply-templates select="movie//*[local-name() = $groupBy][generate-id() = generate-id(key($groupBy, .)[1])]" /> 
    </xsl:template> 

    <xsl:template match="movie//*"> 
     <h1><xsl:value-of select="." /></h1> 
     <ul> 
      <xsl:apply-templates select="key($groupBy, .)/ancestor::movie" /> 
     </ul> 
    </xsl:template> 

    <xsl:template match="movie"> 
     <li><xsl:value-of select="title" /></li> 
    </xsl:template> 
</xsl:stylesheet> 

要按語言分組,請將參數更改爲「languageTerm」。希望添加不同的分組應該不會太難。

請注意,如上所述,這實際上是一個XSLT 1.0。通常,在XSLT 2.0中,您應該使用xsl:for-each-group進行分組。我只是在這裏使用了XSLT 1.0,因爲它可以更容易地添加新組,只需爲每個組添加一個新的xsl:key即可。