I created a test sheet that tried all suggested methods, all
seem to work.
The big question now: which one would be the most efficient
(fastest) one?
A bigger question is whether they are all correct. This one at least seems
wrong, because it has no check for text nodes:
listitem[formatinfo][count(child::*) = 1]
while this solution appears to allow more than one formatinfo child:
match="listitem[formatinfo and not(*[not(self::formatinfo)]) and
(normalize-space() = '')]"
(It also makes the assumption that the formatinfo element will be empty:
this was true of your examples but wasn't stated as a constraint in your
specification of the problem.)
The performance factor will depend on the processor you are using, and also
on the data. For example, the solution that uses normalize-space() is likely
to be very expensive if some of the nodes you are rejecting contain large
amounts of text.
Michael Kay
http://www.saxonica.com/
Here is the sheet for reference:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<bigresult>
<take1>
<xsl:comment>match="listitem [formatinfo [
not (sibling::*
|
sibling::text()[normalize-space()])
]]"</xsl:comment>
<xsl:apply-templates/>
</take1>
<take2>
<xsl:comment>match="listitem[formatinfo and
not(*[not(self::formatinfo)]) and
(normalize-space() = '')]"</xsl:comment>
<xsl:apply-templates mode="take2"/>
</take2>
<take3>
<xsl:comment>match="listitem[formatinfo][count(child::*) =
1]"</xsl:comment>
<xsl:apply-templates mode="take3"/>
</take3>
<take4>
<xsl:comment>select="listitem[node()[last()=1][self::formatinf
o]]"</xsl:comment>
<xsl:apply-templates mode="take4"/>
</take4>
</bigresult>
</xsl:template>
<!-- Clearing out the unwanted elementes one by one -->
<!-- take 1-->
<xsl:template match="listitem [formatinfo [ not
(following-sibling::*
| following-sibling::text()[normalize-space()]) ]]" />
<!-- take 2-->
<xsl:template mode="take2" match="listitem[formatinfo and
not(*[not(self::formatinfo)]) and (normalize-space() = '')]" />
<!-- take 3-->
<xsl:template mode="take3"
match="listitem[formatinfo][count(child::*)
= 1]" />
<!-- take 4-->
<xsl:template mode="take4"
match="llistitem[node()[last()=1][self::formatinfo]]" />
<!-- Standard copy templates for the rest-->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*" mode="take2">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*" mode="take3">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*" mode="take4">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
"Michael Kay" <mike(_at_)saxonica(_dot_)com> wrote on 02/21/2007 09:28:43 PM:
select="listitem[node()[last()=1][self::formatinfo]]"
Michael Kay
-----Original Message-----
From: stephan(_at_)wissel(_dot_)net [mailto:stephan(_at_)wissel(_dot_)net]
Sent: 21 February 2007 13:05
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Filter out elements that have one specific
sub-element and nothing else
Hi there,
I have an XML file like this:
<?xml version="1.0" encoding="UTF-8"?> <funnylist>
<listitem>
<formatinfo color="yellow" />
<stuffinside>Info</stuffinside> MoreInfo
</listitem>
<listitem>
<formatinfo color="blue" />
</listitem>
<listitem>
<formatinfo color="red" />EvenMoreInfo
</listitem>
</funnylist>
I need to filter out this element:
<listitem>
<formatinfo color="blue" />
</listitem>
The rule: if listitem contains only formatinfo and no
other element
or text then remove it.
I have no clue how to formulate the xPath.
Help appreciated.
:-) stw
--~-----------------------------------------------------------------
- XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--