XSL: how to Insert a new element while using copy-of methods

I have the following template & I want to add a new element <Test> which will be reference the
position of this TravDs node


I have :
 
<xsl:template  name="allButDest">
    <xsl:variable name="exclude" select="'Dest'" />
    <xsl:copy-of select="@*" />
    <xsl:copy-of select="*[not(contains($exclude, name()))]" />
  </xsl:template>

Open in new window

   
that copies everything except Dest node.
However, I now need to insert a new node <Test> and have it's value be the node position of the TravDs node. There can be multiple TravDs
so that my output will be something like:


      <Request Id="1234">
            <TravInfo Type="ADT">1</TravInfo>
            <TravDs PaxType="ADT" AssociationID="1"/>
            <Test>1</Test>
            <Dest>
                  <Flight Source="AA" AssociationID="2">
                        <Code>AA</Code>
                        <Number>111</Number>
                  </Flight>
            </Dest>
            ....

How can I update the above template, to check for TravDs and then insert that new element right after it ?
badtz7229Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gertone (Geert Bormans)Information ArchitectCommented:
Typing code on an ipad is not fun, so the below goes untested

You should not use copy-of when you dont want an exact copy
You should use apply-templates and a mechanism of identity copy and  specialised templates with it

Instead of calling a named template, simply do <xsl:apply-templates/> in the template for Request

Then add a template to copy all
<xsl:template match="node()">
   <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="node()"/>
   </xsl:copy>
</xsl:template>

Open in new window

Gertone (Geert Bormans)Information ArchitectCommented:
Next add a template that deletes (= not copies) the dest

<xsl:template match="dest"/>

Open in new window

Gertone (Geert Bormans)Information ArchitectCommented:
Next add an new element right after each TravDs

<xsl:template match="TravDs">
   <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="node()"/>
   </xsl:copy>
   <test>
     <xsl:value-of select="count(preceding-sibling::node())"/>
   </test>
</xsl:template>

Open in new window

Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

badtz7229Author Commented:
<xsl:template  name="allButDest">
    <xsl:variable name="exclude" select="'Dest'" />
    <xsl:copy-of select="@*" />
	
	
    <xsl:for-each select="*[not(contains($exclude, name()))]">
      
      <xsl:choose>
        <xsl:when test="name() = 'TravDs '">
          <TravDs>
            <xsl:attribute name="Type">
              <xsl:value-of select="@Type"/>
            </xsl:attribute>
            <xsl:attribute name="AssociationID">
              <xsl:value-of select="@AssociationID"/>
            </xsl:attribute>
            <Test>
              <xsl:value-of select="@AssociationID"/>
            </Test>
          </TravDs>

        </xsl:when>
        <xsl:otherwise>

          <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:copy-of select="*|text()"/>
          </xsl:copy>

        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
badtz7229Author Commented:
i was able to resolve using my solution. no need for preceding-sibling:
badtz7229Author Commented:
I've requested that this question be closed as follows:

Accepted answer: 0 points for badtz7229's comment #a40917514

for the following reason:

I was able to resolve using the above template logic. this allowed me to insert new node
badtz7229Author Commented:
thank you for your help.
Gertone (Geert Bormans)Information ArchitectCommented:
Well, this is a bit strange.
I provided you a working solution (apart from the value of the attribute due to poor explanation)
The solution you presented your self is technically inferior to my proposal because
- it uses for each where it should simply allow the mechanics of XSLT do the work with apply templates
- it uses a test on name() where a template match (or a self:: would have been better performing)
- it uses a named template where a matching template would be more appropriate
- ...
This is not my personal opinion, this is by common XSLT standards preferrred practice
Rather than ignoring my response, you could have asked for clarification or improvements. Due to forum policy I can not accept your proposal for closing this question.
I suggest accepting my last comment as the accepted answer and the others as the assisted answers
badtz7229Author Commented:
@EE Community Support Moderator

I feel the solution I posted was appropriate for what I was seeking. It's very easy to understand and works successfully. It's the solution I ultimately chose to implement thus is why I selected as resolution. It does everything within one template (simple).
If I return to search for a solution in EE to something similar this is the answer I would understand for what I need.
That's not to say the other solution was not good but as I mentioned if I accept anything else as the actual answer it wouldn't be truth to what I really implemented.
If points to other suggestion are needed  please advise.
Gertone (Geert Bormans)Information ArchitectCommented:
Let me please make a (final) note that the strategy I posted, is commonly understood as the best practice (check any XSLT expert forum) for answering the generic question "how to insert a new element when using xsl:copy-of methods". That is what I would want to read if I were querying the kowledge base. I strongly believe that solutions on EE should at least have the purpose to make us all a better coder.
I understand that Badtz feels in his particular case his approach is simple. So I rest my case.
If you ever get to Europe, let me invite you to one of my XSLT classes where I prove at length that more templates is usually better than one :-)
badtz7229Author Commented:
thanks for your suggestion.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
CSS

From novice to tech pro — start learning today.