Solved

XSL: add new element inside a node i want to copy over

Posted on 2014-02-12
11
467 Views
Last Modified: 2014-02-13
I want to copy over an entire node and it's contents BUT i want to also append a new element as well.

So for instance, I have
<Response>
      <Group Price="100" Num="1">      
       ... (many other nodes within)
      </Group>
</Response>

I want to copy <Group> and inside this node create a new element
<Sequence>1</Sequence>

//where value of Sequence number will be something I'll calculate later  (there could be more than 1 sequence) But for testing purposes just place a "1".


So the output would be
      <Group Price="42800" Num="1">      
       ... (many other nodes within)
      
      <Sequence>1</Sequence>
      
      </Group>



Is this even plausible?
Right now I'm only copying the Group
<xsl:copy-of select="/test/Response/Group"/>
0
Comment
Question by:badtz7229
  • 6
  • 5
11 Comments
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 39854530
You need to build an identity copy
which controls the copy at every level

and have a second more specific template for group
that copies at that level, but adds the Sequence

copy-of for subtrees only works well if you don't need influence on a deeper level

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Group">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
            <Sequence>1</Sequence>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39854542
zc2 suggested in your previous question to move away from for-each in favour of apply-templates. This question is a good example of the power that brings
0
 

Author Comment

by:badtz7229
ID: 39854552
i have a template which i'm using to call this <xsl:copy-of select="/test/Response/Group"/>
(which i know is wrong).
so how then would i incorporate your suggestion within a template?
0
 

Author Comment

by:badtz7229
ID: 39854590
i think i just answered my own question . i have the following

    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
   
    <xsl:template match="/test/Response/Group">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
            <Sequence>1</Sequence>
        </xsl:copy>
    </xsl:template>


and the following call inside another template.
      <xsl:apply-templates select="/test/Response/Group"/>

and it worked.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39854612
yes indeed
replace
<xsl:copy-of select="/test/Response/Group"/>
with
<xsl:apply-templates select="/test/Response/Group"/>

if the identity copy is bothering other nodes, put a mode="inner-copy" or so on each apply-templates and the two templates I posted

like this

<xsl:apply-templates select="/test/Response/Group" mode="inner-copy"/>

and

<xsl:template match="node()" mode="inner-copy">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()" mode="inner-copy"/>
        </xsl:copy>
    </xsl:template>
   
    <xsl:template match="Group" mode="inner-copy">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()" mode="inner-copy"/>
            <Sequence>1</Sequence>
        </xsl:copy>
    </xsl:template>

being specific in the template match
<xsl:template match="/test/Response/Group">

is only necessary if there are Group elements at other levels too
otherwise this is enough
<xsl:template match="Group">
(with or without the mode, depending)
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:badtz7229
ID: 39854661
if i add  mode="inner-copy"/>
i see lots of free text (outputs contents of the input without building it into proper xml).

also, in the <xsl:apply-templates select="/test/Response/Group"/> call, can i pass parameters?
to  <xsl:template match="/test/Response/Group"> so that i can manipulate what the value of <sequence> would be?
0
 

Author Comment

by:badtz7229
ID: 39854664
i ask, bc i've only seen parameters used in call templates and not apply templates
0
 

Author Comment

by:badtz7229
ID: 39854677
sorry, disrgard that last comment about params. yes you can.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39854700
you can pass parameters, but only in XSLT2 you can "tunnel" them
in XSLT1 they will only be picked up by the next level down

about the mode ... aparently the identity copy is used by other nodes as well,
so drop the modes then
0
 

Author Closing Comment

by:badtz7229
ID: 39857280
thank u. this worked.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39857801
welcome
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Newbie CSS questions 4 25
Bootstrap 3 and Angular 2 12 23
Create XML 5 31
MS SQL Database Generating XML using query 21 15
This is a how to build your own CSS3 slideshow and when I say CSS3 I mean just CSS with no javascript in sight! There a few examples online of how to do this but most just show you an example without any explanation, others make it more complicat…
This article discusses four methods for overlaying images in a container on a web page
In this Micro Tutorial viewers will learn how to create a CSS image sprite (In a later tutorial, viewers will learn how to use CSS and HTML to create a navigation menu using this sprite) Open a new Photoshop document with a width of (Icon width)x(N…
In this tutorial viewers will learn how to style rounded corners for elements in CSS using the border-radius property Begin with a normal styled element such as a div: To style all four corners of the div to be the same degree of roundness, use the …

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now