Solved

How copy-of can only copy selected node in XSLT

Posted on 2011-02-11
9
895 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
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 the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

739 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