计数器的XSLT解决方案,记住以前的计数器值

时间:2013-05-22 21:07:23

标签: xml xslt

我想要这个xml:

<AnXML>

 <A1>
  <B1>
   <C1>Hello</C1>
   <C2>HelloAgain</C2>
  </B1>  
  <B2>
    <C3>Yes</C3> 
  <B2>
 </A1>

 <A2>
  <B3>
   <C4>No</C4>
  </B3>
 </A2>

</AnXML>

转变为以下内容:

<AnXML>

 <A1 id="1">
  <B1 id="2" parent="1">
   <C1 id="3" parent="2">Hello</C1>
   <C2 id="4" parent="2">HelloAgain</C2>
  </B1>  
  <B2 id="5" parent="1">
   <C3 id="6" parent="5">Yes</C3> 
  <B2>
 </A1>

 <A2 id="7">
  <B3 id="8" parent="7">
   <C4 id="9" parent="8">No</C4>
  </B3>
 </A2>

</AnXML>

如何使用XSLT执行此操作?当我尝试使用计数时,我无法弄清楚如何保持我希望由子元素引用的生成计数。也许我需要使用除计数之外的其他东西。任何反馈都将不胜感激!

1 个答案:

答案 0 :(得分:0)

您可以使用xsl:number代替count()。您也可以将“父”作为参数传递以跟踪它。

XML输入(已修复为格式良好)

<AnXML>
    <A1>
        <B1>
            <C1>Hello</C1>
            <C2>HelloAgain</C2>
        </B1>
        <B2>
            <C3>Yes</C3>
        </B2>
    </A1>
    <A2>
        <B3>
            <C4>No</C4>
        </B3>
    </A2>
</AnXML>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|text()|processing-instruction()|comment()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <xsl:param name="parent" select="''"/>
        <xsl:variable name="id">
            <xsl:number level="any" count="*" from="/*/*[1]"/>
        </xsl:variable>
        <xsl:copy>
            <xsl:attribute name="id">
                <xsl:value-of select="$id"/>
            </xsl:attribute>
            <xsl:if test="string($parent)">
                <xsl:attribute name="parent">
                    <xsl:value-of select="$parent"/>
                </xsl:attribute>                
            </xsl:if>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="*">
                <xsl:with-param name="parent" select="$id"/>
            </xsl:apply-templates>
            <xsl:apply-templates select="text()|comment()|processing-instruction()"/>
        </xsl:copy>     
    </xsl:template>

</xsl:stylesheet>

XML输出

<AnXML>
   <A1 id="1">
      <B1 id="2" parent="1">
         <C1 id="3" parent="2">Hello</C1>
         <C2 id="4" parent="2">HelloAgain</C2>
      </B1>
      <B2 id="5" parent="1">
         <C3 id="6" parent="5">Yes</C3>
      </B2>
   </A1>
   <A2 id="7">
      <B3 id="8" parent="7">
         <C4 id="9" parent="8">No</C4>
      </B3>
   </A2>
</AnXML>