【问题标题】:XSLT solution for counter that remembers previous counter values用于记住先前计数器值的计数器的 XSLT 解决方案
【发布时间】:2013-05-22 21:07:23
【问题描述】:

我想要这个 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 做到这一点?当我尝试使用计数时,我无法弄清楚如何保持我希望子元素引用的生成计数。也许我需要使用计数以外的东西。任何反馈将不胜感激!

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您可以使用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>
    

    【讨论】:

    • 糟糕!只是注意到文本被丢弃了。也输入错误。 :-/ 已修复。
    • 感谢丹尼尔的回复!
    • @user2382922 - 不客气!感谢您接受我的回答。 +1 提出一个很好的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2021-03-15
    相关资源
    最近更新 更多