473,549 Members | 2,731 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 18961
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**********@gm ail.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:styleshe et
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**********@gm ail.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:styleshe et
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:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="ye s" 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**********@g mail.comwrote in message
news:11******** *************@r 30g2000prh.goog legroups.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**********@gm ail.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
2415
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 like so: <inventory>
15
2551
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 ever made. I don't. I'm wondering what everyone else thinks. I know the smart answer is, use it if you need it and don't if you don't.
3
3806
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 version="1.0" encoding="GB2312"?> <?xml-stylesheet type="text/xsl" href="untitled9.xsl"?> <booklist> <book> <title>bookname1</title> <price>80</price>...
3
7612
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> <data2>fdas</data2>
4
2430
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, I got it working, but the OWL-file is formatted differently and I don't know how to access the elements. I'll post the .owl file below, but this is...
6
3507
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" and "ns0:Company" but I do not want to delete their child nodes("w:p","w:r","w:t"). How can I do this? <ns0:Proposal> <ns0:Company> <w:p> <w:r>
0
1171
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 function to calculate the maximum value of some nodes passed as argument, which i found here :
6
1897
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 <xsl:sortprior to processing, it's not checking against the previous row after the sort but instead the previous row from the original data set. Here...
5
2899
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 basic wrong and for the life of me I can't see it. Please, somebody, cast your eyes over this and tell me what's wrong! First, the XSL stylesheet:...
0
7446
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7715
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7956
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
5368
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3498
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3480
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1935
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1057
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
757
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.