下面我创建了一个简单的XML示例,说明了我的xml是什么样的。我有一个属性,其中包含我想要观看的数字。这是一个计数器,在转换过程中我想在计数器++。
时添加一些东西问题是我的xml文件中的级别数。在这里我只做了三个,但实际上我喜欢8或甚至更多。我需要找到一种方法来比较当前节点与前一节点(反之亦然),但需要考虑这些级别。因此,例如在下面的示例中,需要将id为4的lvl2节点与id为的lvl3节点进行比较,以便找出id属性是否已被提升。
的xml:
<lvl1 id="1">
<lvl2 id="1">
<lvl3 id="1"></lvl3>
<lvl3 id ="2"></lvl3>
</lvl2>
<lvl2 id="2">
<lvl3 id="3"></lvl3>
</lvl2>
<lvl2 id="4"></lvl2>
</lvl1>
由于全球计数器变量是不可能的xslt我目前没有想法,似乎无法在这里或其他任何地方找到任何...
输出类似于:
<ul>
<div>id 1</div>
<li>
<ul>
<li>
<ul>
<li></li>
<div>id 2</div>
<li></li>
</ul>
</li>
<li>
<ul>
<div>id 3</div>
<li></li>
</ul>
</li>
<div>id 4</div>
<li></li>
</ul>
</li>
这里的样式表将xml转换为html输出但没有div:
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.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="/">
<ul>
<xsl:value-of select="@id"/>
<xsl:apply-templates select="lvl1"/>
</ul>
</xsl:template>
<xsl:template match="lvl1">
<li class="{@id}">
lvl 1
<ul>
<xsl:apply-templates select="lvl2"/>
</ul>
</li>
</xsl:template>
<xsl:template match="lvl2">
<li class="{@id}">lvl 2
<ul>
<xsl:apply-templates select="lvl3"/>
</ul>
</li>
</xsl:template>
<xsl:template match="lvl3">
<li class="{@id}">lvl 3
</li>
</xsl:template>
答案 0 :(得分:0)
如果您应用此XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match='/'>
<ul>
<xsl:apply-templates select='*' />
</ul>
</xsl:template>
<xsl:template match="*">
<li>
<div>
<xsl:value-of select='@id' />
<xsl:if test='count(*)>0'>
<ul>
<xsl:apply-templates select='*' />
</ul>
</xsl:if>
</div>
</li>
</xsl:template>
</xsl:stylesheet>
你得到的东西可能就是你所要求的:
<ul>
<li>
<div>1<ul>
<li>
<div>1<ul>
<li>
<div>1</div>
</li>
<li>
<div>2</div>
</li>
</ul>
</div>
</li>
<li>
<div>2<ul>
<li>
<div>3</div>
</li>
</ul>
</div>
</li>
<li>
<div>4</div>
</li>
</ul>
</div>
</li>
</ul>
答案 1 :(得分:0)
问题比看起来要复杂得多,因为preceding::
并不总是在这里找到当前元素之前的最后@id
。您还需要检查父项@id
并考虑根位置。此代码使用问题中给出的XML生成所需的结果。请参阅我的评论。
<xsl:template match="/">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:template>
<xsl:template match="*">
<!-- get preceding (or parent) id -->
<xsl:variable name="lastId">
<xsl:choose>
<!-- try to get id from first preceding element -->
<xsl:when test="preceding::*[1]/@id">
<xsl:value-of select="preceding::*[1]/@id"/>
</xsl:when>
<!-- there could still be ids in parent elements -->
<xsl:when test="../@id">
<xsl:value-of select="../@id"/>
</xsl:when>
<!-- or this is the root element -->
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- now compare current and last id -->
<xsl:if test="@id > $lastId">
<div>
<xsl:text>id </xsl:text>
<xsl:value-of select="@id"/>
</div>
</xsl:if>
<!-- create list item -->
<li>
<!-- check for subelements -->
<xsl:if test="*">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:if>
</li>
</xsl:template>
根据您的实际情况,您可能希望将match="*"
限制为match="*[starts-with(local-name(),'lvl')]"
,如LarsH的评论中所建议的那样。