2012-04-19 85 views
1

我目前正在研究將下列xml轉換爲有序列表的XSL腳本。請參閱下面的輸入和輸出示例。順便說一句,我正在使用XSLT 2.0。XSLT列表轉換

**Input:** 
<xml> 
    <numberedList>1. Number List 1</numberedList> 
    <unnumberedList>Child List 1</unnumberedList> 
    <unnumberedList>Child List 2</unnumberedList> 
    <unnumberedList>Child List 3</unnumberedList> 
    <numberedList>2. Number List 2</numberedList> 
    <unnumberedList>Child List 1</unnumberedList> 
    <numberedList>3. Number List 3</numberedList> 
</xml> 

**Output:** 
<html> 
<ol> 
    <li>1. Number List 1</li> 
    <li> 
     <ul> 
      <li>Child List 1</li> 
      <li>Child List 2</li> 
      <li>Child List 3</li> 
     </ul> 
    </li> 
    <li>2. Number List 2</li> 
    <li> 
     <ul> 
      <li>Child List 1</li> 
     </ul> 
    </li> 
    <li>3. Number List 3</li> 
</ol> 
</html> 

任何幫助將不勝感激。謝謝!

+0

這是功課?你試過什麼了? – 2012-04-19 22:11:50

+0

嗨,羅布,我嘗試使用與組相鄰,但它不會伎倆。 – 2012-04-19 22:14:29

回答

3

一個試圖在Dimitre的XSLT 2.0解決方案的改進:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <html> 
    <ol> 
    <xsl:for-each-group select="*" group-adjacent="name()"> 
     <xsl:choose> 
     <xsl:when test="self::numberedList"> 
      <xsl:apply-templates select="current-group()"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <li><ul><xsl:apply-templates select="current-group()"/></ul></li> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each-group> 
    </ol> 
    </html> 
</xsl:template> 

<xsl:template match="numberedList|unnumberedList"> 
    <li><xsl:apply-templates/></li> 
</xsl:template> 

</xsl:stylesheet> 
+0

如果我不想生成「if-less」代碼,我可以這樣寫。我認爲消除顯式條件(即使有時必須使用模式來實現這一點)有助於可讀性和可理解性。當然,我的方法可能被認爲是極端的,這個解決方案表明,當使用節制時,條件可能產生「自然」的解決方案。 – 2012-04-20 12:05:33

+0

+1爲一個很好的答案。 – 2012-04-20 12:51:00

+0

非常感謝解決方案傢伙!我很感激。他們都會工作很好,但我更喜歡最短的解決方案。 – 2012-04-20 14:33:41

0

毫無疑問,這可以做得更容易,但請嘗試以下操作。
說明:不言而喻:-)
請注意,這也適用於XSLT 1.0。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.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="xml"> 
     <html> 
      <ol> 
       <xsl:apply-templates select="numberedList[1]"/> 
      </ol> 
     </html> 
    </xsl:template> 
    <xsl:template match="numberedList"> 
     <li> 
      <xsl:value-of select="."/> 
     </li> 
     <xsl:apply-templates select="following-sibling::*[1]"/> 
    </xsl:template> 
    <xsl:template match="unnumberedList [local-name(preceding-sibling::*[1]) = 'numberedList']"> 
     <li> 
      <ul> 
       <li> 
        <xsl:value-of select="."/> 
       </li> 
       <xsl:apply-templates select="following-sibling::*[1] [local-name() = 'unnumberedList']"/> 
      </ul> 
     </li> 
     <xsl:apply-templates select="following-sibling::numberedList[1]"/> 
    </xsl:template> 
    <xsl:template match="unnumberedList [local-name(preceding-sibling::*[1]) = 'unnumberedList']"> 
     <li> 
      <xsl:value-of select="."/> 
     </li> 
     <xsl:apply-templates select="following-sibling::*[1] [local-name() = 'unnumberedList']"/> 
    </xsl:template> 
</xsl:stylesheet> 

哪給出以下結果:

<?xml version="1.0" encoding="UTF-8"?> 
<html> 
    <ol> 
     <li>1. Number List 1</li> 
     <li> 
      <ul> 
       <li>Child List 1</li> 
       <li>Child List 2</li> 
       <li>Child List 3</li> 
      </ul> 
     </li> 
     <li>2. Number List 2</li> 
     <li> 
      <ul> 
       <li>Child List 1</li> 
      </ul> 
     </li> 
     <li>3. Number List 3</li> 
    </ol> 
</html> 
2

I.甲稍短XSLT 1.0溶液

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

<xsl:key name="kUlist" match="unnumberedList" 
    use="generate-id(preceding-sibling::* 
         [not(self::unnumberedList)][1] 
        )"/> 

<xsl:template match="/*"> 
    <html> 
    <xsl:apply-templates select="numberedList[1]" mode="first"/> 
    </html> 
</xsl:template> 

<xsl:template match="numberedList" mode="first"> 
    <ol> 
    <xsl:apply-templates select=". | following-sibling::*"/> 
    </ol> 
</xsl:template> 

<xsl:template match="*"> 
    <li><xsl:apply-templates /></li> 
</xsl:template> 

<xsl:template match= 
"unnumberedList 
     [not(preceding-sibling::*[1][self::unnumberedList])]"> 
    <li> 
    <ul> 
     <xsl:apply-templates mode="inUList" select= 
      "key('kUlist', generate-id(preceding-sibling::*[1]))"/> 
    </ul> 
    </li> 
</xsl:template> 

<xsl:template match="*" mode="inUList"> 
    <li><xsl:value-of select="."/></li> 
</xsl:template> 
<xsl:template match="unnumberedList"/> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<xml> 
    <numberedList>1. Number List 1</numberedList> 
    <unnumberedList>Child List 1</unnumberedList> 
    <unnumberedList>Child List 2</unnumberedList> 
    <unnumberedList>Child List 3</unnumberedList> 
    <numberedList>2. Number List 2</numberedList> 
    <unnumberedList>Child List 1</unnumberedList> 
    <numberedList>3. Number List 3</numberedList> 
</xml> 

的希望,正確的結果產生:

<html> 
    <ol> 
     <li>1. Number List 1</li> 
     <li> 
     <ul> 
      <li>Child List 1</li> 
      <li>Child List 2</li> 
      <li>Child List 3</li> 
     </ul> 
     </li> 
     <li>2. Number List 2</li> 
     <li> 
     <ul> 
      <li>Child List 1</li> 
     </ul> 
     </li> 
     <li>3. Number List 3</li> 
    </ol> 
</html> 

II。一個XSLT 2.0溶液 - 30%短於I.

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <html> 
    <ol> 
    <xsl:for-each-group select="*" group-adjacent="name()"> 
     <xsl:apply-templates select="current-group()"/> 
    </xsl:for-each-group> 
    </ol> 
    </html> 
</xsl:template> 

<xsl:template match="*" mode="#default inUList"> 
    <li><xsl:apply-templates/></li> 
</xsl:template> 

<xsl:template match= 
    "unnumberedList[preceding-sibling::*[1][not(self::unnumberedList)]]"> 
    <li> 
    <ul> 
    <xsl:apply-templates mode="inUList" select="current-group()"/> 
    </ul> 
    </li> 
</xsl:template> 
<xsl:template match="unnumberedList"/> 
</xsl:stylesheet> 

當該XSLT 2.0變換對相同的XML文檔(以上)應用中,相同的正確的結果產生

<html> 
    <ol> 
     <li>1. Number List 1</li> 
     <li> 
     <ul> 
      <li>Child List 1</li> 
      <li>Child List 2</li> 
      <li>Child List 3</li> 
     </ul> 
     </li> 
     <li>2. Number List 2</li> 
     <li> 
     <ul> 
      <li>Child List 1</li> 
     </ul> 
     </li> 
     <li>3. Number List 3</li> 
    </ol> 
</html>