473,382 Members | 1,376 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

XSL: how to remove nodes from the XML tree? (advanced)

Hey!
How would you do the following task?

Let you have an XML tree on input.
Suppose, there is a special kind of node you want to remove.
Let it have "bad" name.
Each "bad" node has a parent node, obviously.
In case there are no children left in the parent after removal of all
the "bad" nodes, the parent must also be removed.
And this rule is applied to all the ancetors of the "bad" node
recursively.

How would you do this in XSLT?
I don't know :(

Example input:
<a>
<b>
<c>
<bad/>
<bad/>
</c>
</b>
<d>
<bad/>
</d>
<e/>
</a>

Desired output:
<a>
<e/>
</a>

Pasha

Apr 26 '07 #1
6 18938
Standard approach: Start with the identity transform, then add templates
for anything that doesn't want to simply be copied over.

You want to discard any node that contains <bad/somewhere in its
subtree. Those nodes can be expressed as *[.//bad]. Write a template
that matches that and outputs nothing.

Exception: You want to keep the top-level element. Write a template that
explicitly matches it and always outputs it, recursively processing its
contents. Or modify the "anything containing bad" pattern to explicitly
not match the top-level element.

Details are left as an exercise for the student.

--
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
Apr 26 '07 #2

pa**********@gmail.com wrote:
Suppose, there is a special kind of node you want to
remove. Let it have "bad" name. Each "bad" node has a
parent node, obviously. In case there are no children left
in the parent after removal of all the "bad" nodes, the
parent must also be removed. And this rule is applied to
all the ancetors of the "bad" node recursively.

How would you do this in XSLT?
Try reading XPath/XSLT tutorials. Note that this is a bit
tricky to implement in XSLT1, you would need some fairly
evil XPath expressions to filter out unneeded nodes. XSLT2
would make things much easier for you. Reading something
about identity transformation and exclusion templates
should be extremely useful.

Just for the heck of it:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match=
"
*
[..][descendant::bad]
[not(descendant::*[not(*)][not(self::bad)])]
"/>
</xsl:stylesheet>

Hm, let's see...

"bad.xml" 12L, 96C written
xsltproc bad.xsl bad.xml
<?xml version="1.0"?>
<a>
<e/>
</a>
>
Yep. It even seems to work on your sample document.

Oh, and stop using the google groups. GG never worked all
that well for posting on the usenet newsgroups, but it got
beyond bad in the last few days--seems like their ng
archives suddenly broke down in a fairly spectacular
fashion, and no one even bothered to fix them.

--
roy axenov
Apr 26 '07 #3
M
Hi Roy,

Not quite there...

If you apply your stylesheet to...
<a>
<bad/>
<b>
<c>
<bad/>
<bad/>
</c>
</b>
<d>
<bad/>
</d>
<e/>
</a>

You get left with a <badelement left in.

I think the empty template needs to be...
<xsl:template match="*[descendant-or-self::bad and parent::*]"/>
Cheers
M

"roy axenov" <r_******@mail.ruwrote in message
news:f0**********@aioe.org...
>
pa**********@gmail.com wrote:
Suppose, there is a special kind of node you want to
remove. Let it have "bad" name. Each "bad" node has a
parent node, obviously. In case there are no children left
in the parent after removal of all the "bad" nodes, the
parent must also be removed. And this rule is applied to
all the ancetors of the "bad" node recursively.

How would you do this in XSLT?

Try reading XPath/XSLT tutorials. Note that this is a bit
tricky to implement in XSLT1, you would need some fairly
evil XPath expressions to filter out unneeded nodes. XSLT2
would make things much easier for you. Reading something
about identity transformation and exclusion templates
should be extremely useful.

Just for the heck of it:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match=
"
*
[..][descendant::bad]
[not(descendant::*[not(*)][not(self::bad)])]
"/>
</xsl:stylesheet>

Hm, let's see...

"bad.xml" 12L, 96C written
xsltproc bad.xsl bad.xml
<?xml version="1.0"?>
<a>
<e/>
</a>

Yep. It even seems to work on your sample document.

Oh, and stop using the google groups. GG never worked all
that well for posting on the usenet newsgroups, but it got
beyond bad in the last few days--seems like their ng
archives suddenly broke down in a fairly spectacular
fashion, and no one even bothered to fix them.

--
roy axenov

Apr 27 '07 #4
As replied in another newsgroup, here is one solution:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:strip-space elements="*"/>

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

<xsl:template match="bad"/>

<xsl:template match=
"*[* and not(descendant::*[not(*) and not(self::bad)])]"/>
</xsl:stylesheet>

Let's have a little bit more complex xml, such as this one:

<a>
<b>
<c>
<bad/>
<bad/>
</c>
</b>
<d>
<bad/>
</d>
<e/>
<f>
<bad/>
<good/>
<bad/>
</f>
</a>
The transformation above produces the required result:

<a>
<e/>
<f>
<good/>
</f>
</a>
Cheers,
Dimitre Novatchev
<pa**********@gmail.comwrote in message
news:11*********************@r30g2000prh.googlegro ups.com...
Hey!
How would you do the following task?

Let you have an XML tree on input.
Suppose, there is a special kind of node you want to remove.
Let it have "bad" name.
Each "bad" node has a parent node, obviously.
In case there are no children left in the parent after removal of all
the "bad" nodes, the parent must also be removed.
And this rule is applied to all the ancetors of the "bad" node
recursively.

How would you do this in XSLT?
I don't know :(

Example input:
<a>
<b>
<c>
<bad/>
<bad/>
</c>
</b>
<d>
<bad/>
</d>
<e/>
</a>

Desired output:
<a>
<e/>
</a>

Pasha

Apr 29 '07 #5
M <m@m.comwrote in
<1t****************@newsfe1-win.ntli.net>:
"roy axenov" <r_******@mail.ruwrote in message
news:f0**********@aioe.org...
>pa**********@gmail.com wrote:
Suppose, there is a special kind of node you want to
remove. Let it have "bad" name. Each "bad" node has a
parent node, obviously. In case there are no children
left in the parent after removal of all the "bad"
nodes, the parent must also be removed. And this rule
is applied to all the ancetors of the "bad" node
recursively.
xsltproc bad.xsl bad.xml
<?xml version="1.0"?>
<a>
<e/>
</a>
>

Yep. It even seems to work on your sample document.

I think the empty template needs to be...
<xsl:template match="*[descendant-or-self::bad and
parent::*]"/>
That would remove any element that has any <bad/>
descendants. I don't believe that's what the OP was asking
for.

--
Pavel Lepin
May 2 '07 #6
Dimitre, thank you so much, the transformation works perfectly!
Besides, I have even managed to understand how does it work. :) Hope
to use this technique in future.

Very professional, thanks!

May 2 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Jim Bancroft | last post by:
Hi everyone, Could someone reccomend a way to remove duplicate/outmoded nodes in an XML document? I didn't describe that well, so let me give an example. For instance, if I have an XML doc...
15
by: Simon Harvey | last post by:
Hi everyone, I am fairly new to learning about xsl and xml, but one thing I have noticed is that anyone offering a tutorial or lesson on it seems to think that its the most incredible invention...
3
by: ppl | last post by:
I'm very new to XSL and have come across a stumbling block with a recent assignment at work. I need to translate from XML to XML using an XSL style sheet. Here is the input XML: <?xml...
3
by: Michael | last post by:
Hello, I am creating an XSL that is going to create a report from XML we recieve from another system. The XML would look like: <report> <page> <header1> <data1>asdf</data1>...
4
by: Fredrik Henricsson | last post by:
Hey, I'm building an ontology in Protégé and I want to transform parts of it (e.g. the instances) to HTML with XSL. When I was transforming another file with 'simple' XML-tags like <author> before,...
6
by: Nikhil Patel | last post by:
Hi all, Following is a portion of an XML document. I need to remove all nodes that belong to ns0 without deleting their child nodes. So in the following example , I want to delete "ns0:Proposal"...
0
by: Nicolas | last post by:
Hi, I've been working on this problem for a couple of days and now i have no more ideas. first, this problem only happens with jdk 1.5, everything was fine with jdk1.4. I'm using a...
6
by: Christoph | last post by:
I'm trying to come up with a stylesheet where, when the rows are displayed, duplicate game names are not shown on subsequent rows. It works but doesn't work properly. If I sort the data using...
5
by: Simon Brooke | last post by:
This is supposed to be a very simple XSL stylesheet to strip styling information out of HTML documents - it could not be more basic. And yet, it doesn't work. I'm obviously getting something very...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.