我目前正在开发一个XSL脚本,它将以下xml转换为有序列表。请参考下面的输入和输出示例。我顺便使用XSLT 2.0。
**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 :(得分: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>
答案 1 :(得分:2)
<强>予。稍微短一点的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%
<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>
当在同一个XML文档(上面)上应用此XSLT 2.0转换时,会生成相同的正确结果:
<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 :(得分: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>