Subject: RE: Filter out elements that have one specific sub-element and nothing else
From: stephan@xxxxxxxxxx
Date: Thu, 22 Feb 2007 10:01:43 +0800
|
Thx so much to all who replied.
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?
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::formatinfo]]"</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@xxxxxxxxxxxx> wrote on 02/21/2007 09:28:43 PM:
> select="listitem[node()[last()=1][self::formatinfo]]"
>
> Michael Kay
>
>
> > -----Original Message-----
> > From: stephan@xxxxxxxxxx [mailto:stephan@xxxxxxxxxx]
> > Sent: 21 February 2007 13:05
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: 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
|