使用xslt在特定点添加xml节点

时间:2010-08-13 01:43:18

标签: xml xslt

我有以下xml并希望在其中插入额外的xml:

<root>
    <steps>
        <step name="step1" type="process">
            <steps>
                <step name="substep1">
                </step>
            </steps>
        </step>
        <step name="step2" type="process">
            <steps>
                <step name="substep1">
                <!-- more substeps...-->
                </step>
            </steps>
        </step>
        <step name="step3" type="process">
            <steps>
                <step name="substep1">
                </step>
                <step name="substep2">
                </step>
                <!-- more substeps...-->
            </steps>
        </step>
        <!-- THE BELOW IS WHAT I WISH TO ADD... and it has to be here -->
        <step name="reference">
            <!-- These stuff have been hardcoded in my xsl so its fine -->
        </step>
        <!-- ends -->
    </steps>
    <references>
        <reference name="reference1">
        </reference>
        .
        .
        .
    </references>
</root>

正如我在xml示例中所写的那样,我希望在大多数步骤中添加一个额外的步骤元素作为最后一步。我已经在我的xsl中硬编码了xml片段,所以我需要做的就是找到移动到xml树特定点的最佳逻辑,这样我就可以调用模板并添加snipet。

这样做的推荐/最佳方法是什么?

感谢。

1 个答案:

答案 0 :(得分:6)

此转化

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

 <xsl:param name="pAddition">
   <step name="reference">
     <XXX/>
   </step>
 </xsl:param>

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

 <xsl:template match="/*/steps/step[position()=last()]">
  <xsl:call-template name="identity"/>
  <xsl:copy-of select="$pAddition"/>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档时

<root>
    <steps>
        <step name="step1" type="process">
            <steps>
                <step name="substep1">
                </step>
            </steps>
        </step>
        <step name="step2" type="process">
            <steps>
                <step name="substep1">
                <!-- more substeps...-->
                </step>
            </steps>
        </step>
        <step name="step3" type="process">
            <steps>
                <step name="substep1">
                </step>
                <step name="substep2">
                </step>
                <!-- more substeps...-->
            </steps>
        </step>
    </steps>
    <references>
        <reference name="reference1">
        </reference>
        .
        .
        .
    </references>
</root>

生成想要的正确结果

<root>
   <steps>
      <step name="step1" type="process">
         <steps>
            <step name="substep1"/>
         </steps>
      </step>
      <step name="step2" type="process">
         <steps>
            <step name="substep1"><!-- more substeps...--></step>
         </steps>
      </step>
      <step name="step3" type="process">
         <steps>
            <step name="substep1"/>
            <step name="substep2"/><!-- more substeps...-->
         </steps>
      </step>
      <step name="reference">
         <XXX/>
      </step>
   </steps>
   <references>
      <reference name="reference1"/>
        .
        .
        .
    </references>
</root>

请注意

  1. ** 身份规则用于按原样复制所有节点。

  2. 要插入的XML片段(为方便起见)指定为全局xsl:param的正文。在实际应用程序中,它将位于单独的xml文件中,并将使用xslt document()函数获取。

  3. 与插入点匹配的模板通过调用标识规则来复制匹配的节点。然后它复制xsl:param的内容,因此新的conted将完全输出到所需的插入点。