淺談對的理解

http://www.cnblogs.com/it_mac/archive/2010/06/27/1766151.html


前幾天做XML的練習,目的是把給出的XML文檔按要求的格式顯示出來,用的是xslt。

給出的 C04Ex1.xml 文件內容如下:

複製代碼
1 <?xml version="1.0" encoding="UTF-8"?> 2  <?xml:stylesheet type="text/xsl" href="C04Ex1.xsl"?> 3 <collection> 4 <cd> 5 <title>Boys for Pele</title> 6 <artist>Tori Amos</artist> 7 <tracks> 8 <track type="vocal"> 9 <name>Horses</name> 10 <length>3.5</length> 11 </track> 12 <track type="instrumental"> 13 <name>Blood roses</name> 14 <length>3.2</length> 15 </track> 16 <track type="vocal"> 17 <name>Father lucifer</name> 18 <length>3.8</length> 19 </track> 20 <track type="instrumental"> 21 <name>Professional widow</name> 22 <length>4.1</length> 23 </track> 24 <track type="vocal"> 25 <name>Mr. Zebra</name> 26 <length>3.6</length> 27 </track> 28 </tracks> 29 </cd> 30 <cd> 31 <title>The Ghosts that Hunt me</title> 32 <artist>Crash TestDummies</artist> 33 <tracks> 34 <track type="vocal"> 35 <name>Winter song</name> 36 <length>4.3</length> 37 </track> 38 <track type="instrumental"> 39 <name>Comin's back soon</name> 40 <length>4.1</length> 41 </track> 42 <track type="vocal"> 43 <name>Superman's song</name> 44 <length>4.1</length> 45 </track> 46 <track type="vocal"> 47 <name>Here on earth</name> 48 <length>3.1</length> 49 </track> 50 </tracks> 51 </cd> 52 </collection>
複製代碼

 

要求輸出的格式如下圖所示: 

 

  一開始,筆者的輸出的結果如下:

 

  讀者可以發現比要求的格式多出了兩行(上圖中紅圈所標示的內容)。

  對應的xsl文檔如下:

複製代碼
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:template match="/"> 4 <html> 5 <body></body> 6 <xsl:apply-templates/> 7 </html> 8 </xsl:template> 9 <xsl:template match="collection"> 10 <xsl:apply-templates/> 11 </xsl:template> 12 13 <xsl:template match="cd"> 14 <center> 15 <font size="5"><b><xsl:value-of select="title"/>:</b></font> 16 <font size="5"><i><xsl:value-of select="artist"/></i></font> 17 </center> 18 <xsl:apply-templates/> 19 </xsl:template> 20 21 <xsl:template match="tracks"> 22 <center> 23 <table border="1"> 24 <tr> 25 <th>Name</th> 26 <th>Length</th> 27 <th>Type</th> 28 </tr> 29 <xsl:for-each select="track"> 30 <tr> 31 <td><xsl:value-of select="name"/></td> 32 <td><xsl:value-of select="length"/></td> 33 <td><xsl:value-of select="@type"/></td> 34 </tr> 35 </xsl:for-each> 36 </table> 37 <br/><br/> 38 </center> 39 </xsl:template> 40 </xsl:stylesheet> 41
複製代碼

 

  經過思考和測試,發現問題出在“<xsl:apply-templates/>”(在上文中已突出顯示)。

  由於寫上述xsl文件的時候對<xsl:apply-templates/>的理解還不到位,只是機械的模仿一些例子把<xsl:apply-templates/>加到一些模板內。因此一開始的時候的那個問題總是無法解決。後來請教了同學後纔對<xsl:apply-templates/>有了更深刻的理解。

  

  經過自己總結得出如下的幾個結論:

  一、<xsl:apply-templates/>一般只會出現在只含有html標籤的模板中,亦即通常不會出現在含有xsl標籤的模板中;

  二、<xsl:apply-templates/>的作用是通知解析器把當前匹配的節點的所有子節點和已定義的模板進行匹配,如有相符的則運用對應的模板,如無模板匹配的節點將按文本形式顯示對應的內容;

  三、<xsl:apply-templates/>只能用在當前節點的所有子節點都有模板可以匹配的模板中。

  

  明白了以上幾點,上述xsl文件的錯誤就很好理解了。

  首先,我定義了用於匹配“cd”的模板,然後定義了“title”和“artist”的顯示格式。接着,我加了一個<xsl:apply-templates/>。此時,由於匹配的節點是“cd”,而“title”和“artist”,還有後面的“tracks”都是“cd”的子節點,所以解析器爲每個節點尋找匹配的模板。由於沒有定義與“title”和“artist”匹配的模板,所以“title”和“artist”的內容又以文本的形式輸出了一次(如果匹配“title”和“artist”的模板有定義,則又會按照定義的模板重新輸出一次,正確的寫法請參照下文中的可行版本1、2),而“tracks”節點能夠找到對應的模板與之對應,故能正常顯示。

  

  根據對<xsl:apply-templates/>的進一步理解,筆者又寫出了兩個可行的版本,分別如下:

可行版本一:

複製代碼
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:template match="/"> 4 <html> 5 <body></body> 6 <xsl:apply-templates/> 7 </html> 8 </xsl:template> 9 <xsl:template match="collection"> 10 <xsl:apply-templates/> 11 </xsl:template> 12 <xsl:template match="cd"> 13 <center> 14 <font size="5"><b><xsl:value-of select="title"/>:</b></font> 15 <font size="5"><i><xsl:value-of select="artist"/></i></font> 16 <xsl:for-each select="tracks"> 17 <table border="1"> 18 <tr> 19 <th>Name</th> 20 <th>Length</th> 21 <th>Type</th> 22 </tr> 23 <xsl:for-each select="track"> 24 <tr> 25 <td><xsl:value-of select="name"/></td> 26 <td><xsl:value-of select="length"/></td> 27 <td><xsl:value-of select="@type"/></td> 28 </tr> 29 </xsl:for-each> 30 </table> 31 <br/><br/> 32 </xsl:for-each> 33 </center> 34 </xsl:template> 35 </xsl:stylesheet> 36
複製代碼

  

可行版本2:

複製代碼
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:template match="/"> 4 <html> 5 <body><xsl:apply-templates/></body> 6 </html> 7 </xsl:template> 8 9 <xsl:template match="collection"> 10 <xsl:apply-templates/> 11 </xsl:template> 12 13 <xsl:template match="cd"> 14 <center> 15 <xsl:apply-templates/> 16 </center> 17 </xsl:template> 18 19 <xsl:template match="title"> 20 <font size="5"><b><xsl:value-of select="."/>:</b></font> 21 </xsl:template> 22 23 <xsl:template match="artist"> 24 <font size="5"><i><xsl:value-of select="."/></i></font> 25 </xsl:template> 26 27 <xsl:template match="tracks"> 28 <table border="1"> 29 <tr> 30 <th>Name</th> 31 <th>Length</th> 32 <th>Type</th> 33 </tr> 34 <xsl:apply-templates/> 35 </table> 36 <br/><br/> 37 </xsl:template> 38 39 <xsl:template match="track"> 40 <tr> 41 <td><xsl:value-of select="name"/></td> 42 <td><xsl:value-of select="length"/></td> 43 <td><xsl:value-of select="@type"/></td> 44 </tr> 45 </xsl:template> 46 </xsl:stylesheet> 47
複製代碼

 

可行版本的顯示效果如下圖:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章