SANbuddies
asked on
How copy-of can only copy selected node in XSLT
Hi,
Question for Copy
input:
<Rel><IRel UID1="3a4d1d2909d0" UID2="35fe61082294" DefUID="AssetSupplier" />
<IObject UID="3a4d1d2909d0.AssetSup plier.35fe 61082294" />
<SPXSupplier>
<ISPFOrganization /><ISPFAdminItem /><IObject UID="b73ebb87-cd36-4c25-b9 ed-35fe610 82294" 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.AssetSup plier.35fe 61082294" />
</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.
Question for Copy
input:
<Rel><IRel UID1="3a4d1d2909d0" UID2="35fe61082294" DefUID="AssetSupplier" />
<IObject UID="3a4d1d2909d0.AssetSup
<SPXSupplier>
<ISPFOrganization /><ISPFAdminItem /><IObject UID="b73ebb87-cd36-4c25-b9
</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.AssetSup
</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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
sorry guys I am away from my computer wont be able to check your solution until I get back !
Appreciate your suggestions.
Appreciate your suggestions.
ASKER
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/>
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/>
"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>
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>
ASKER
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.
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.
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"/>
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(
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"/>
ASKER
and if have to process the value of foo which will later dicide whether that node has to be copied or not?
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"
<xsl:template match="abc[@foo = 'bar']"/>
will remove all <abc> on the condition that the value of attribute "foo" equals "bar"
To selective copy only desired elements try to implement something like in the sample below:
Open in new window