我正在尝试将一些PHP代码逻辑实现到XSLT中。
xml结构看起来像
输入:
<parent>
<child>
<id>1</id>
<value>11</value>
</child>
<child>
<id>2</id>
<value>22</value>
</child>
<child>
<id></id>
<value>22</value>
</child>
<child>
<id></id>
<value>00</value>
</child>
<child>
<id></id>
<value>00</value>
</child>
<parent>
我试图在XSLT中实现的php(逻辑)中的sudo代码如下:
var Index = 1;
for each "child"{
if( "id" is not empty ){
Index += "id" + 1;
}else{
if( previous "value" == current "value" ){
"id" = Index;
Index++;
}else{
"id" = 1;
Index = 2;
}
}
}
据我了解,在XSLT中,我们没有一个可以在每次迭代中更新的计数器/变量。我相信我可以使用preceding-sibling
将以前的值与当前值进行比较,但是如何计算此时的索引?如果可以轻松/简单地使用XSLT 2.0,则可以使用。
有任何想法建议吗?
转换后的输出应如下所示:
输出:
<parent>
<child>
<id>1</id>
<value>11</value>
</child>
<child>
<id>2</id>
<value>22</value>
</child>
<child>
<id>6</id> <!-- "id" = "Index" calculated so far, since current value (22) = previous value (22) -->
<value>22</value>
</child>
<child>
<id>1</id> <!-- "id" = 1 since current value (00) != previous value (22) -->
<value>00</value>
</child>
<child>
<id>2</id> <!-- "id" = "Index" calculated so far, since currnet value (00) = previous value (00) -->
<value>00</value>
</child>
<parent>
答案 0 :(得分:1)
这是尝试使用XSLT 3和xsl:iterate
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="parent">
<xsl:copy>
<xsl:iterate select="child">
<xsl:param name="index" select="1"/>
<xsl:param name="previous-value" select="()"/>
<xsl:variable name="value" select="value"/>
<xsl:variable name="id"
select="(id[has-children()], if ($value = $previous-value) then $index else 1)[1]"/>
<xsl:variable name="index"
select="if (id[has-children()])
then $index + $id + 1
else if ($value = $previous-value)
then $index + 1
else 2"/>
<xsl:apply-templates select=".">
<xsl:with-param name="id" select="$id" tunnel="yes"/>
</xsl:apply-templates>
<xsl:next-iteration>
<xsl:with-param name="index" select="$index"/>
<xsl:with-param name="previous-value" select="$value"/>
</xsl:next-iteration>
</xsl:iterate>
</xsl:copy>
</xsl:template>
<xsl:template match="id[not(has-children())]">
<xsl:param name="id" tunnel="yes"/>
<xsl:copy>{$id}</xsl:copy>
</xsl:template>
</xsl:stylesheet>