2012-04-19 78 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>