ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> xsl-list
xsl-list
RE: [xsl] Delete XML Node
by Wendell Piez other posts by this author
Oct 31 2002 9:43PM messages near this date
RE: [xsl] Delete XML Node | [xsl] Using substring call with for-each/apply templates
Deepak,

I've been somewhat reluctant to respond to your post, though it's easy 
enough, since it's actually hard to determine what the best answer is.

The simple answer is "wrap the output for your <Y>  in a simple xsl:if to 
test whether your condition for outputting it is met". So your code might be:

...
<xsl:for-each select="Y"> 
   <xsl:if test="*"> <!-- tests whether any element children of a Y exist -->
     <Y> ...</Y>
   </xsl:if> 
</xsl:for-each> 

But I rather think, looking at your input and desired output, that there 
are better solutions. Whether they are actually better depend on the exact 
purposes of your transform, as well as what range of inputs it has to 
handle, etc. So, for example, if your input is

<X> 
    <A> A</A>
    <Y> </Y>
</X> 

and your stylesheet is tasked with the job of *copying the input except Y 
elements that have no children*, this can easily be accomplished with a 
modified "identity stylesheet" (a stylesheet that copies the source tree to 
the result), like so:

<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="*"> 
   <!-- the default template for an element simply copies that element --> 
   <xsl:copy> 
     <xsl:apply-templates/> 
   </xsl:copy> 
</xsl:template> 

<xsl:template match="Y[not(*)]"/> 
<!-- except Y elements with no element children are removed --> 

</xsl:stylesheet> 

This will be both more robust, and easier to maintain and extend, than the 
"pull" approach you are taking using the for-each instructions.

If you don't understand how this is working, you want to do a bit of 
research on templates, apply-templates and the XSLT processing model, 
including the effect of the built-in templates.

Good luck,
Wendell

At 04:03 PM 10/31/2002, you wrote:
> Whoops, I shot myself in the foot here....
> 
> sorry folks I am new to XSL.... and pardon my ignorrance
> 
> To clarify things, I want an XSL which would output a <Y> if and only if 
> it has a sub element in this case a <Z>. In the current example I have 
> only one sub element <Z> but there can be more than one sub-element of <Y>.
> 
> e.g.
> 
> <Y>
> <Z></Z>
> <D></D>
> ......
> </Y>
> 
> I do not want <Y></Y> to appear in the output if all the sub-elements do 
> not map.
> 
> Thanks,
> Deepak


======================================================================
Wendell Piez                            mailto:wapiez@[...].com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
   Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
Thread:
Deepak Rao
Wendell Piez

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved