开发者

Adding xml nodes at a specific point using xslt

开发者 https://www.devze.com 2023-01-11 14:52 出处:网络
I have the following xml and want to insert additional xml into it: <root> <steps> <step name=\"step1\" type=\"process\">

I have the following xml and want to insert additional xml into it:

<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>

As I've written in the xml sample, I wish to add an additional step element as the very last step within the outter most steps. I have the xml snippet already hardcoded in my xsl so all I needed to do is to find the best logic to move to that particular point of the xml tree so I can call the template and have that snipet added in.

What is the recommended/best approach to do this?

Thanks.


This transformation:

<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>

when applied on this XML document:

<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>

produces the wanted, correct result:

<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>

Do note:

  1. **The identity rule is used to copy all nodes as is.

  2. The XML fragment to be inserted is specified (for convenience) as the body of a global xsl:param. In a realistic application it will be in a separate xml file and will be obtained using the xslt document() function.

  3. The template that matches the insertion point copies the matched node by calling the identity rule. then it copies the content of the xsl:param and thus the new conted is output exactly at the desired insertion point.

0

精彩评论

暂无评论...
验证码 换一张
取 消