473,387 Members | 1,517 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,387 software developers and data experts.

removal of empty nodes resulting from application of other templates

I'm trying to write a stylesheet which removes nodes which are empty
as a result of other template processing.

For example, given the following xml, I'd like to:
- remove all "b" elements
- remove all "a" elements which, as a result of "b" element
removal, now have no children

so, starting with:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
<a>
<b/>
</a>
<a>
<b/>
<c/>
</a>
</doc>

I'd like to end up with:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
<a>
<c/>
</a>
</doc>

I've written this stylesheet:

<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="*"/>

<!-- matches all nodes and attributes -->
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

<!-- rule for element "a", ought to reproduce "a" only if it has
children -->
<xsl:template match="//a">
<xsl:if test="count(./*) &gt; 0">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>

<!-- remove all b nodes -->
<xsl:template match="//b" priority="3" name="b-removal"/>

</xsl:stylesheet>

but the resultant output has not removed the empty "a" element:
<doc>
<a/>
<a>
<c/>
</a>
</doc>

Can anyone suggest a way to do this?

Thanks,

Ted

Feb 13 '07 #1
3 2034
On 13 Feb., 23:57, tschwa...@revasystems.com wrote:
I'm trying to write a stylesheet which removes nodes which are empty
as a result of other template processing.
How about applying that stylesheet to your data twice?

Regards,
Johannes
Feb 14 '07 #2
jo*************@gmx.net wrote:
>>I'm trying to write a stylesheet which removes nodes which are empty
as a result of other template processing.
XSLT 1.0 doesn't have any built-in ability to do two-pass processing.
The usual solution is to run two stylesheets in succession, or the same
one twice.

If you MUST do it in a single stylesheet, the usual workaround is to use
the EXSLT node-set function. Do a first pass outputting into a variable
to obtain a Result Tree Fragment, then use exslt:node-set() to make that
available to XSLT in a form that it can walk over again, generating the
final output. Modes may be useful in keeping the two passes separate, if
the behavior is different in one than in the other.

(XSLT 2.0 -- still not widely supported, unfortunately, since it adds a
lot of complexity along with the simplifications -- eliminates the
distinction between node-sets and RTFs, and can do what I've just
described without needing a "standard nonstandard" helper.)

--
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
Feb 14 '07 #3
On Feb 13, 9:32 pm, Joseph Kesselman <keshlam-nos...@comcast.net>
wrote:
johanneskrue...@gmx.net wrote:
>I'm trying to write a stylesheet which removes nodes which are empty
as a result of other template processing.

XSLT 1.0 doesn't have any built-in ability to do two-pass processing.
The usual solution is to run two stylesheets in succession, or the same
one twice.

If you MUST do it in a single stylesheet, the usual workaround is to use
the EXSLT node-set function. Do a first pass outputting into a variable
to obtain a Result Tree Fragment, then use exslt:node-set() to make that
available to XSLT in a form that it can walk over again, generating the
final output. Modes may be useful in keeping the two passes separate, if
the behavior is different in one than in the other.

(XSLT 2.0 -- still not widely supported, unfortunately, since it adds a
lot of complexity along with the simplifications -- eliminates the
distinction between node-sets and RTFs, and can do what I've just
described without needing a "standard nonstandard" helper.)

--
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
Thanks for the help! As I would like to apply the templates in one
pass I've successfully used the approach of using included
stylesheets and modes described above. Here are the stylesheets:
first-pass.xsl:

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

<!-- matches all nodes and attributes -->
<xsl:template match="node()|@*" name="identity" mode="first-pass">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="first-pass"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/">
<xsl:apply-templates mode="first-pass"/>
</xsl:template>

<!-- remove all b nodes -->
<xsl:template match="//b" priority="3" name="b-removal" mode="first-
pass"/>

</xsl:stylesheet>

second-pass.xsl:

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

<!-- matches all nodes and attributes -->
<xsl:template match="node()|@*" name="identity" mode="second-pass">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="second-pass"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/">
<xsl:apply-templates mode="second-pass"/>
</xsl:template>

<!-- rule for element "a", ought to reproduce a only if it has
children -->
<xsl:template match="//a" mode="second-pass">
<xsl:if test="count(./*) &gt; 0">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

main.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:include href="first-pass.xsl"/>
<xsl:include href="second-pass.xsl"/>

<xsl:template match="/">
<xsl:variable name="first">
<xsl:apply-templates mode="first-pass" />
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($first)" mode="second-
pass" />
</xsl:template>

</xsl:stylesheet>
Then with execution of main.xsl against the source xml, I get the
desired output:

<doc>
<a>
<c/>
</a>
</doc>

Thanks again.

Feb 15 '07 #4

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

Similar topics

3
by: Erhard Schwenk | last post by:
Hi there, Maybe this is a faq, if so, point me the URL please. I have to do some xml to xml transformations in xslt, where I have - simplified - the following: input: <doc>...
1
by: Johannes Lebek | last post by:
Hi there, somehow, I cannot access nodes that are stored in a variable. I'm using Xalan 2.5.1 and the following commands: ================ BEGIN ==================== <xsl:variable...
4
by: Jyrki Keisala | last post by:
Hi, I have an XML file which I want to present as a HTML table, and I'm looking for a quick way of defaulting all empty elements in my XML file to a nbsp (using the   notation) in my XSL...
4
by: dd | last post by:
Given the bolow sample, I need to count the elements <quick> with a child 'yes'. The result for this sample should, of couse, be '1', but I cannot figure out how to write the expression in the...
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>...
2
by: | last post by:
Okay, this is probably a really stupid question - but I just can't figure it out. I have a large xml document which is being transformed into another using ..net xsl - some elements inside of...
1
by: tMan | last post by:
whats the xpath to get all the empty nodes in a document. in the xml below i want to get the nodes <empty> and <t> all other nodes either have a child node or text in them <root> <test> <se>...
4
by: Michael Frost | last post by:
Loading and saving a xml document in .net creates whitespace in empty nodes! loading an empty node like: <node></node> ..net saves as: <node> </node>
4
by: Tarique Jawed | last post by:
Alright I needed some help regarding a removal of a binary search tree. Yes its for a class, and yes I have tried working on it on my own, so no patronizing please. I have most of the code working,...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
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,...
0
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...

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.