xsl中的条件自动增量

时间:2009-08-21 14:13:29

标签: xslt auto-increment xslt-2.0

我有这样的XML:

<V>
  <W>
    <X>1</X> 
  </W>
  <W>
    <Y>1</Y> 
  </W>
  <W>
    <X>1555</X> 
  </W>
  <W>
    <X>1</X> 
  </W>
</V>

我想这样做:

<entity ID="start">
    <f ID="NewField">0001</f>
    <f ID="NewField">0001</f>
    <f ID="NewField">0002</f>
    <f ID="NewField">0003</f>
</entity>

当字段为V / W / X时,NewField应增加1,与标签V / W / X一样多。 同样适用于V / W / Y.

我使用的XSL是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<entity ID="start">
    <xsl:for-each select="V/W">
        <xsl:if test="X">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
        <xsl:if test="Y">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
    </xsl:for-each>
</entity>
</xsl:template>
</xsl:stylesheet>

但它给了我一个错误的结果,如下所示:

<entity ID="start">
  <f ID="NewField">0001</f>
  <f ID="NewField">0002</f> 
  <f ID="NewField">0003</f> 
  <f ID="NewField">0004</f> 
</entity>

3 个答案:

答案 0 :(得分:1)

如果您想使用XSLT为节点编号,那么the xsl:number element可以提供帮助:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <entity ID="start">
      <xsl:apply-templates select="descendant::X | descendant::Y"/>
    </entity>
  </xsl:template>

  <xsl:template match="X | Y">
    <f ID="NewField"><xsl:number level="any" format="0000"/></f>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

我认为你正在寻找像count(preceding::X)表达式这样的东西。当然你可能想让它变得更复杂,然后关注数字格式,但这听起来像是你正在寻找的起点。

答案 2 :(得分:0)

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="V">
    <entity ID="start">
      <xsl:apply-templates select="W/X|W/Y" />
    </entity>
  </xsl:template>

  <xsl:template match="X|Y">
    <f ID="NewField">
      <xsl:variable name="counter" select="
        count(
          parent::W/preceding-sibling::W/*[name() = name(current())]
        ) + 1
      " />
      <xsl:value-of select="format-number($counter, '0000')" />
    </f>
  </xsl:template>

</xsl:stylesheet>

此:

parent::W/preceding-sibling::W/*[name() = name(current())]

选择与当前元素同名的所有前面的元素。例如,如果执行点在此节点上:

<X>1555</X> 

它向上一级(parent::W),然后选择所有前面的<W>兄弟,以及它选择名称为{{1}的任何子(*)的兄弟姐妹} - 因为XX元素的名称。

计算得到的节点集并递增1。 current()用于生成一个很好的干净输出:

format-number()