Solved

How copy-of can only copy selected node in XSLT

Posted on 2011-02-11
9
882 Views
Last Modified: 2013-11-18
Hi,
Question for Copy
input:
<Rel><IRel UID1="3a4d1d2909d0" UID2="35fe61082294" DefUID="AssetSupplier" />
<IObject UID="3a4d1d2909d0.AssetSupplier.35fe61082294" />
   <SPXSupplier>
   <ISPFOrganization  /><ISPFAdminItem /><IObject UID="b73ebb87-cd36-4c25-b9ed-35fe61082294"   Description="local supplier made in form (10C)" Name="CASTROL1200" /><ISupplierOrganization />
   </SPXSupplier>
</Rel>

Output:
I only want to skip SPXSupplier and its child node in my output
<Rel><IRel UID1="3a4d1d2909d0" UID2="35fe61082294" DefUID="AssetSupplier" />
<IObject UID="3a4d1d2909d0.AssetSupplier.35fe61082294" />
</Rel>

currently I am using this copy which copy all the things including the child,
<xsl:copy-of select="self::node()"/>
I only want <Rel>, <IRel> and <IObject> tags. excluding other stuff.
0
Comment
Question by:SANbuddies
  • 4
  • 4
9 Comments
 
LVL 18

Expert Comment

by:zc2
ID: 34872567
As soon as I know, the copy-of always copies all the subnodes.
To selective copy only desired elements try to implement something like in the sample below:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>
	<xsl:template match="/">
		<xsl:apply-templates select="*"/>
	</xsl:template>

	<xsl:template match="Rel|IRel|IObject|@*">
		<xsl:copy>
			<xsl:apply-templates select="@*"/>
			<xsl:apply-templates select="IRel|IObject|@*"/>
		</xsl:copy>
	</xsl:template>

</xsl:stylesheet>

Open in new window

0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 50 total points
ID: 34872797
The best way to simulate a copy-of is by having an identity copy
(example 1)
The identity copy does exactly what a deep copy such as xslcopy-of does

by specialising you can remove some nodes

if you want to remove SPX Supplier, you just add a template for doing so (example2)

This approach (removeing what needs to be removed) is easier to embed and extend then explicitely copying what needs to be added
example 1
----------
<?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:stylesheet>

example 2
---------
<?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="SPXSupplier"/>
</xsl:stylesheet>

Open in new window

0
 

Author Comment

by:SANbuddies
ID: 34915050
sorry guys I am away from my computer wont be able to check your solution until I get back !
Appreciate your suggestions.
0
 

Author Comment

by:SANbuddies
ID: 34941679
Gertno:
hi,
   thanks for the answer, can you tell me if I am going to use the same approach i can skip all nodes by just creating template for each.
Does the level of the nodes matter?
<abc>
  <level1>
      <level2>
      <level2/>
  <level1/>
<abc/>
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.

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 34941876
"Does the level of nodes matter?"

No, that is exactly the difference between my approach and zc2's approach,
This method of reconstructing the deep tree (whilst removing some parts)
works regardless of the depth

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

This template assures that every node that does not have its own template gets copied AND that its children are processed

You can safely add an empty template for each node you want to remove
So that answers "i can skip all nodes by just creating template for each"

If you need to just remove the tags, but keep some of the children, you can add a template like this
    <xsl:template match="abc">
            <xsl:apply-templates select="node()"/>
    </xsl:template>
0
 

Author Comment

by:SANbuddies
ID: 34941953
how about Node() how does it work or what node() really means in xslt?
and similar with apply-templates='node()' this is some sort of nesting ?

and if I want to skip some attributes is it possible? I know that its not same as nodes  and attributes are treated in different way.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 34941984
node() means any children
this includes child elements, text nodes, process instructions and comments
it excludes attributes

attributes are all copied with the <xsl:copy-of select="@*"/>

if you want to exclude an attribute 'foo' you can do this

<xsl:copy-of select="@*[not(local-name() = 'foo')]"/>

if you leave the line out completely, no attributes will be copied

if you only want to copy the attribute 'foo' you can do this
<xsl:copy-of select="@foo"/>
0
 

Author Comment

by:SANbuddies
ID: 34943116
and if have to process the value of foo which will later dicide whether that node has to be copied or not?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 34943149
You can always add tests in predicates, but I think it would be wise if you would add an example here

<xsl:template match="abc[@foo = 'bar']"/>

will remove all <abc> on the condition that the value of attribute "foo" equals "bar"

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

Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

759 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

19 Experts available now in Live!

Get 1:1 Help Now