2009-08-21 22 views
1

での条件付き自動インクリメント:私はこのようなXMLを持っているXSL

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

私はそれこのような何か作りたい:フィールドがV/W/Xのとき

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

その後、NewFieldにすべきですタグV/W/Xが見つかった回数だけ1だけインクリメントされます。 同様に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> 

答えて

0

私はあなたがcount(preceding::X)表現のようなものを探していると思いますが。もちろん、それをもっと複雑にして、数値書式に注意したいかもしれませんが、それはあなたが探している出発点のように思えます。

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> 

それは1つの上のレベルアップ(parent::W)になる、そしてすべての先行<W>兄弟を選択し、それらのそれはの名前を持つすべての子(*)を選択しますX - Xcurrent()要素の名前です。

結果のノードセットがカウントされ、1だけインクリメントされます。その後、the xsl:number elementは助けることができる

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

、あなたが使用する理由、特定の理由があります ' parent :: 'axis(明示的には、定義によっては最大でも1つのノードしか持たない)を' ..'ではなく - どちらかというとあいまいではないようです。 –

+0

あなたは正しいです、 '' .. ''は同じで、私はそれを知っています。私はそれがもっと表現力豊かなので、私はそれをやっている。 XPathを読むとき、予想される文書構造は即座に明瞭ですが、 '' .. ''はあいまいさを残します。 – Tomalak

1

は、あなたが数XSLTを持つノードをしたい場合::format-number()は素敵なきれいな出力を生成するために使用されて好奇心のうち

<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> 
関連する問題