473,320 Members | 1,841 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,320 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 18935
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...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
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...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.