我遇到了XSLT的问题。我在<level>
内有一组兄弟节点(<source>
),我希望在节点的重叠中进行转换(即每个级别都会在其先前的兄弟节点内呈现)。
<?xml version="1.0"?>
<sources>
<source mode="manual" name="test1">
<level>blablabla Level1</level>
<level>this is the second level</level>
<level>this is the third level</level>
</source>
</sources>
我想要的输出是一个imbricated html版本(删节,重叠是这里的事情):
<form class="source manual">
source > <input value="test1" name="sourceName" type="text">
<!-- LEVEL #1 -->
<p class="deepnessIndicator">Deepness: <strong>1</strong></p>
<div class="deepnessContainer">
<!-- LEVEL #2 -->
next-level:
<p class="deepnessIndicator">Deepness: <strong>2</strong></p>
<div class="deepnessContainer">
<!-- LEVEL #3 -->
next-level:
<p class="deepnessIndicator">Deepness: <strong>3</strong></p>
</div>
</div>
</form>
不幸的是我编写的XSL失败了,这里是源码(我试图缩短但是):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="sources">
<xsl:apply-templates select="*" />
</xsl:template>
<!-- Main template here -->
<xsl:template match="source[@mode='manual']">
<form class="source manual">
source > <input type="text" name="sourceName" value="{@name}" />
<!-- Here's what I call first the recursion
the parameter is the # of the <level>
that should be processed -->
<xsl:call-template name="sourceLevelRecursion">
<xsl:with-param name="currentLevel">1</xsl:with-param>
</xsl:call-template>
</form>
</xsl:template>
<!-- Recursion template -->
<xsl:template name="sourceLevelRecursion">
<xsl:param name="currentLevel" />
<!-- this apply-templates should apply on only
one node because of the selector but it won't -->
<xsl:apply-templates mode="deepnessHeader" select="./level[$currentLevel]">
<xsl:with-param name="currentLevel"><xsl:value-of select="$currentLevel" /></xsl:with-param>
</xsl:apply-templates>
<xsl:if test="level[$currentLevel+1]">
<div class="deepnessContainer">
<!-- Recursion Call here -->
<xsl:call-template name="sourceLevelRecursion">
<xsl:with-param name="currentLevel"><xsl:value-of select="$currentLevel+1" /></xsl:with-param>
</xsl:call-template>
</div>
</xsl:if>
</xsl:template>
<xsl:template mode="deepnessHeader" match="level">
<xsl:param name="currentLevel" />
<p class="deepnessIndicator">Deepness: <strong><xsl:value-of select="$currentLevel" /></strong></p>
</xsl:template>
<xsl:template match="text()" />
我获得的最终错误输出是:
<form class="source manual">
source > <input value="test1" name="sourceName" type="text">
<p class="deepnessIndicator">Deepness: <strong>1</strong></p>
<p class="deepnessIndicator">Deepness: <strong>1</strong></p>
<p class="deepnessIndicator">Deepness: <strong>1</strong></p>
<div class="deepnessContainer">
next-level:
<p class="deepnessIndicator">Deepness: <strong>2</strong></p>
<p class="deepnessIndicator">Deepness: <strong>2</strong></p>
<p class="deepnessIndicator">Deepness: <strong>2</strong></p>
<div class="deepnessContainer">
next-level:
<p class="deepnessIndicator">Deepness: <strong>3</strong></p>
<p class="deepnessIndicator">Deepness: <strong>3</strong></p>
<p class="deepnessIndicator">Deepness: <strong>3</strong></p>
</div>
</div>
</form>
如您所见,申请:
<xsl:apply-templates mode="deepnessHeader" select="./level[$currentLevel]">
匹配
<xsl:template mode="deepnessHeader" match="level">
匹配三次,源XML中每个<level>
一次。但是,apply-templates中的选择器应该只选择一个节点呢?
答案 0 :(得分:2)
使用强>:
<xsl:apply-templates mode="deepnessHeader"
select="./level[position()=$currentLevel]">
XSLT 1.0是“弱类型”。 XSLT处理器不知道$currentLevel
包含的值应该被视为整数。
因此$currentLevel
被视为布尔值 - 因为谓词中的任何非整数表达式都应该。但是,如果实际值可以转换为整数,则任何不同于0的整数值都将被视为true()
,整个谓词为true()
,因此不会过滤掉任何内容。
记住:
在XPath 1.0中,任何Expr[someInteger]
,其中someInteger
是整数文字,是:Expr[position() = someInteger]