2012-09-10 36 views
-1

我有這個XML文件,我需要通過xsl/t將它轉換爲表格。用xsl-TVGuide呈現XML

<?xml version="1.0" encoding="ISO-8859-1"?> 

<TVGuide start="2001-07-05" end="2001-07-05"> 
    <Channel> 
    <Name>BBC1</Name> 
    <Program> 
     <Start>2001-07-05T19:00:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>A QuestionOfSport</Series> 
     <Title></Title> 
    </Program> 
    <Program rating="5" flag="favorite"> 
     <Start>2001-07-05T19:30:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>EastEnders</Series> 
     <Title></Title> 
     <Description> 
     Mark's health scare forces him to reconsider his future with Lisa, 
     while Jamie is torn between Sonia and Zoe. 
     </Description> 
     <CastList> 
     <CastMember> 
      <Character><Name>Zoe Slater</Name></Character> 
      <Actor><Name>Michelle Ryan</Name></Actor> 
     </CastMember> 
     <CastMember> 
      <Character><Name>Jamie Mitchell</Name></Character> 
      <Actor><Name>Jack Ryder</Name></Actor> 
     </CastMember> 
     <CastMember> 
      <Character><Name>Sonia Jackson</Name></Character> 
      <Actor><Name>Natalie Cassidy</Name></Actor> 
     </CastMember> 
     </CastList> 
     <Writers> 
     <Writer><Name>Nick Saltrese</Name></Writer> 
     <Writer><Name>Julie Wassmer</Name></Writer> 
     </Writers> 
     <Director><Name>Stewart Edwards</Name></Director> 
     <Producer><Name>Emma Turner</Name></Producer> 
    </Program> 
    <Program type="documentary"> 
     <Start>2001-07-05T20:00:00</Start> 
     <Duration>PT45M</Duration> 
     <Series></Series> 
     <Title>Get Real with Casualty</Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T20:45:00</Start> 
     <Duration>PT45M</Duration> 
     <Series>Lottery</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T21:30:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>Panorama</Series> 
     <Title></Title> 
    </Program> 
    </Channel> 
    <Channel> 
    <Name>BBC2</Name> 
    <Program> 
     <Start>2001-07-05T19:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>Snooker</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T20:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>HomeFront</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T21:00:00</Start> 
     <Duration>PT50M</Duration> 
     <Series>WildAfrica</Series> 
     <Title></Title> 
    </Program> 
    <Program flag="interesting"> 
     <Start>2001-07-05T21:50:00</Start> 
     <Duration>PT40M</Duration> 
     <Series>Taboo</Series> 
     <Title>Nakedness</Title> 
    </Program> 
    </Channel> 
    <Channel> 
    <Name>ITV</Name> 
    <Program> 
     <Start>2001-07-05T19:00:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>Emmerdale</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T19:30:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>CoronationStreet</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T20:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>Millionaire</Series> 
     <Title></Title> 
    </Program> 
    <Program type="drama"> 
     <Start>2001-07-05T21:00:00</Start> 
     <Duration>PT2H</Duration> 
     <Series></Series> 
     <Title>Hot Money</Title> 
    </Program> 
    </Channel> 
    <Channel> 
    <Name>Channel 4</Name> 
    <Program> 
     <Start>2001-07-05T19:00:00</Start> 
     <Duration>PT55M</Duration> 
     <Series>Channel4News</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T19:55:00</Start> 
     <Duration>PT5M</Duration> 
     <Series>SlotArt</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T20:00:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>Brookside</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T20:30:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>Brookside</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T21:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>Swallow</Series> 
     <Title></Title> 
    </Program> 
    <Program flag="favorite"> 
     <Start>2001-07-05T22:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series>AllyMcBeal</Series> 
     <Title></Title> 
    </Program> 
    </Channel> 
    <Channel> 
    <Name>Channel 5</Name> 
    <Program> 
     <Start>2001-07-05T19:00:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>MovieChartShow</Series> 
     <Title></Title> 
    </Program> 
    <Program> 
     <Start>2001-07-05T19:30:00</Start> 
     <Duration>PT30M</Duration> 
     <Series>FiveNews</Series> 
     <Title></Title> 
    </Program> 
    <Program type="entertainment"> 
     <Start>2001-07-05T20:00:00</Start> 
     <Duration>PT1H</Duration> 
     <Series></Series> 
     <Title>The World's Worst Drivers Caught On Tape</Title> 
    </Program> 
    <Program type="film"> 
     <Start>2001-07-05T21:00:00</Start> 
     <Duration>PT1H55M</Duration> 
     <Series></Series> 
     <Title>Black and White</Title> 
    </Program> 
    </Channel> 
</TVGuide> 

我知道大概問題出在xsl文件中。我不是專家,我真的很樂意幫助你。

這是xsl文件。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="hatchala" match="/TVGuide/Channel/Program" use="Start"/> 
    <xsl:template match="/"> 

     <table border="1"> 

      <tr>hours 
       <xsl:call-template name="tvchan"/> 
      </tr> 
      <tr> 
       <th> 
       <xsl:call-template name="hour"/> 
       </th> 
      </tr> 

     </table> 
    </xsl:template> 
    <xsl:template name="tvchan"> 
    <xsl:for-each select="/TVGuide/Channel"> 

     <th> 
     <td> 
      <xsl:value-of select ="Name"/> 
     </td> 

     </th> 
    </xsl:for-each> 

    </xsl:template> 
    <xsl:template name="hour"> 
      <xsl:for-each select="/TVGuide/Channel/Program[not(./Start=following::Start)]"> 
      <xsl:sort select="Start"/> 
      <xsl:variable name="zman" select ="Start"/> 
      <tr> 
       <td> 
       <xsl:value-of select="Start"/> 
       </td> 

       <xsl:for-each select="/TVGuide/Channel/Program[Start=$zman]"> 
       <xsl:variable name="name1"> 
        <xsl:choose> 
        <xsl:when test="Title!=''"> 
         <xsl:value-of select="Title"/> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="Series"/> 
        </xsl:otherwise> 

        </xsl:choose> 
       </xsl:variable> 
       <td> 
        <xsl:value-of select="$name1"/> 

       </td> 
      </xsl:for-each> 
      </tr> 
      </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

結果應該顯示一個包含所有程序和他們小時的表格。

http://dl.dropbox.com/u/99771726/table.png

非常感謝你的幫助。

回答

2

首先,如果您使用的是XSLT1.0,則可以使用稱爲Muenchian Grouping的技術來獲取所有程序的獨特啓動時間。這包括設置一個鍵來查找程序的開始元素。

<xsl:key name="hatchala" match="Program" use="Start"/> 

注意你不一定需要完整的XPath的計劃元素,關鍵還是看看他們在任何級別(如果你有不同級別的這些元素你只量化的東西,想限制他們)。

然後,以獲得不同的開始時間,你會擡頭而它們恰巧是該元素在其開始時間的關鍵第一次出現在節目

<xsl:apply-templates 
    select="/TVGuide/Channel/Program 
     [generate-id() = generate-id(key('hatchala', Start)[1])]" mode="header"> 

(使用「模式」的將很快清楚,因爲最終的XSLT將多次匹配程序元素)。

我還要定義一鍵查找程序給定信道在給定的起始時間

<xsl:key name="hatchala2" match="Program" use="concat(../Name, '|', Start)"/> 

然後,對於一個給定的起始時間,你會遍歷所有通道,是這樣的... 。

<xsl:apply-templates select="/TVGuide/Channel" mode="program"> 
    <xsl:with-param name="Start" select="Start"/> 
</xsl:apply-templates> 

然後模板匹配這一點,可以用查找程序中的關鍵

<xsl:template match="Channel" mode="program"> 
    <xsl:param name="Start"/> 
    <td> 
     <xsl:apply-templates select="key('hatchala2', concat(Name, '|', $Start))" mode="program"/> 
    </td> 
</xsl:template> 

下面是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:key name="hatchala" match="Program" use="Start"/> 
    <xsl:key name="hatchala2" match="Program" use="concat(../Name, '|', Start)"/> 

    <xsl:template match="/TVGuide"> 
     <table border="1"> 
     <tr> 
      <th>hours</th> 
      <xsl:apply-templates select="Channel" mode="header"/> 
     </tr> 
     <tr> 
      <th> 
       <xsl:apply-templates select="/TVGuide/Channel/Program[generate-id() = generate-id(key('hatchala', Start)[1])]" mode="header"> 
        <xsl:sort select="Start"/> 
       </xsl:apply-templates> 
      </th> 
     </tr> 
     </table> 
    </xsl:template> 

    <xsl:template match="Channel" mode="header"> 
     <th> 
     <xsl:value-of select="Name"/> 
     </th> 
    </xsl:template> 

    <xsl:template match="Program" mode="header"> 
     <tr> 
     <td> 
      <xsl:value-of select="Start"/> 
     </td> 
     <xsl:apply-templates select="/TVGuide/Channel" mode="program"> 
      <xsl:with-param name="Start" select="Start"/> 
     </xsl:apply-templates> 
     </tr> 
    </xsl:template> 

    <xsl:template match="Channel" mode="program"> 
     <xsl:param name="Start"/> 
     <td> 
     <xsl:apply-templates select="key('hatchala2', concat(Name, '|', $Start))" mode="program"/> 
     </td> 
    </xsl:template> 

    <xsl:template match="Program" mode="program"> 
     <xsl:choose> 
     <xsl:when test="Title!=''"> 
      <xsl:value-of select="Title"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="Series"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

再下面是輸出

<table border="1"> 
    <tr> 
     <th>hours</th> 
     <th>BBC1</th> 
     <th>BBC2</th> 
     <th>ITV</th> 
     <th>Channel 4</th> 
     <th>Channel 5</th> 
    </tr> 
    <tr> 
     <th> 
     <tr> 
      <td>2001-07-05T19:00:00</td> 
      <td>A QuestionOfSport</td> 
      <td>Snooker</td> 
      <td>Emmerdale</td> 
      <td>Channel4News</td> 
      <td>MovieChartShow</td> 
     </tr> 
     <tr> 
      <td>2001-07-05T19:30:00</td> 
      <td>EastEnders</td> 
      <td/> 
      <td>CoronationStreet</td> 
      <td/> 
      <td>FiveNews</td> 
     </tr> 
     <tr> 
      <td>2001-07-05T19:55:00</td> 
      <td/> 
      <td/> 
      <td/> 
      <td>SlotArt</td> 
      <td/> 
     </tr> 
     <tr> 
      <td>2001-07-05T20:00:00</td> 
      <td>Get Real with Casualty</td> 
      <td>HomeFront</td> 
      <td>Millionaire</td> 
      <td>Brookside</td> 
      <td>The World's Worst Drivers Caught On Tape</td> 
     </tr> 
     <tr> 
      <td>2001-07-05T20:30:00</td> 
      <td/> 
      <td/> 
      <td/> 
      <td>Brookside</td> 
      <td/> 
     </tr> 
     <tr> 
      <td>2001-07-05T20:45:00</td> 
      <td>Lottery</td> 
      <td/> 
      <td/> 
      <td/> 
      <td/> 
     </tr> 
     <tr> 
      <td>2001-07-05T21:00:00</td> 
      <td/> 
      <td>WildAfrica</td> 
      <td>Hot Money</td> 
      <td>Swallow</td> 
      <td>Black and White</td> 
     </tr> 
     <tr> 
      <td>2001-07-05T21:30:00</td> 
      <td>Panorama</td> 
      <td/> 
      <td/> 
      <td/> 
      <td/> 
     </tr> 
     <tr> 
      <td>2001-07-05T21:50:00</td> 
      <td/> 
      <td>Nakedness</td> 
      <td/> 
      <td/> 
      <td/> 
     </tr> 
     <tr> 
      <td>2001-07-05T22:00:00</td> 
      <td/> 
      <td/> 
      <td/> 
      <td>AllyMcBeal</td> 
      <td/> 
     </tr> 
     </th> 
    </tr> 
</table> 

請注意使用的xsl:應用模板的代替的xsl:for-每個避免過多的嵌套代碼,試圖讓它更易於閱讀。

如果您希望主要使用XSL版本:換每個,試試這個XSLT而不是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:key name="hatchala" match="Program" use="Start"/> 
    <xsl:key name="hatchala2" match="Program" use="concat(../Name, '|', Start)"/> 

    <xsl:template match="/TVGuide"> 
     <table border="1"> 
     <tr> 
      <th>hours</th> 
      <xsl:for-each select="Channel"> 
       <th> 
        <xsl:value-of select="Name"/> 
       </th> 
      </xsl:for-each> 
     </tr> 
     <tr> 
      <th> 
       <xsl:for-each select="/TVGuide/Channel/Program[generate-id() = generate-id(key('hatchala', Start)[1])]"> 
        <xsl:sort select="Start"/> 

        <xsl:variable name="Start" select="Start" /> 
        <tr> 
        <td> 
         <xsl:value-of select="$Start"/> 
        </td> 
        <xsl:for-each select="/TVGuide/Channel"> 
         <td> 
          <xsl:apply-templates select="key('hatchala2', concat(Name, '|', $Start))" /> 
         </td> 
        </xsl:for-each> 
        </tr>     
       </xsl:for-each> 
      </th> 
     </tr> 
     </table> 
    </xsl:template> 

    <xsl:template match="Program"> 
     <xsl:value-of select="Series"/> 
    </xsl:template> 

    <xsl:template match="Program[Title!='']"> 
     <xsl:value-of select="Title"/> 
    </xsl:template> 
</xsl:stylesheet> 

這應該生成相同的輸出。請注意,我已經離開了一個xsl:apply-templates,因爲它產生了模式匹配的好處,並提供了替代xsl:選擇

+0

哇,非常感謝您的幫助! – dash

+0

如果我想用xsl:for-each寫出xslt文件,我該怎麼做?感謝幫助。 – dash

+0

我已將xsl:for-each樣本添加到我的答案中! –