This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: testing element's contents
- From: Wendell Piez <wapiez at mulberrytech dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Thu, 03 Oct 2002 12:04:53 -0400
- Subject: Re: [xsl] testing element's contents
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Nate,
At 11:08 AM 10/3/2002, you wrote:
hi all,
Thanks to everyone who gave me advice on my previous
post about images and captions. Now, I have another
tricky lil' xslt problem. If a paragraph element
contains ONLY a media element OR a media element
surrounded by a link element and nothing more (read,
no other nodes, be they text or not), such as:
<p><img
src="http://www.mylocal.gov/images/nasausa.gif"
height="255" width="432"/></p>
I need to strip the p tags out of resulting output.
Okay. Quibbles: translated into XSL-speak, what you want to do is process
the children of p, but not create any node for the p itself. (XSLT doesn't
know from 'tags', it knows about nodes, meaning things like elements and
attributes.) Also: you seem to be giving us something different from
<Media>....
However, if it does contain other nodes, such as:
<p><img
src="http://www.mylocal.gov/images/nasausa.gif"
height="255" width="432"/>This is my news release. The
authors will be typing the news release content in
here! I am not sure what this news release is even
about, but lets see how it comes out in XML, shall we?
As I see it coming out as:</p>
I need to leave it alone.
Could your problem be restated fairly as "if there's any text content in
the paragraph, I need a paragraph in my output to wrap it, otherwise not"?
If so, you could do:
<xsl:template match="p">
<xsl:choose>
<xsl:when test="normalize-space(.)">
<!-- this tests true if the paragraph has any string value
at all after whitespace normalization. This only occurs
if the paragraph or any of its descendants has non-whitespace
text content -->
<p>
<xsl:apply-templates/>
</p>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This could also be expressed as two simpler templates:
<xsl:template match="p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="p[not(normalize-space(.))]">
<xsl:apply-templates/>
</xsl:template>
Here, the first template serves as a default, and the second one fires
whenever it matches but not otherwise (it has a higher priority since its
match is more complex).
If your logic is more complex than what I'm inferring (e.g. if it is
actually more dependent on the actual type of nodes you have down there,
Media or whatever) you need to do something closer to what you already
have. Refine the logic of your requirement and you can refine the code....
Cheers,
Wendell
Here is what I have so far. It only looks to see if a
media element or a media element wrapped by a link
element exists, but does not consider if there is a
text node after a media or link element.
<xsl:template match="p">
<xsl:choose>
<xsl:when test="((descendant::*[1])[self::Link] and
(descendant::*[2])[self::Media]) or
(descendant::*[1])[self::Media]"><xsl:apply-templates
/></xsl:when>
<xsl:otherwise><p><xsl:apply-templates
/></p></xsl:otherwise>
</xsl:choose>
</xsl:template>
======================================================================
Wendell Piez mailto:wapiez@mulberrytech.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