|
Subject: RE: [xsl] Filter out elements that have one specific sub-element and nothing else From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Thu, 22 Feb 2007 08:38:15 -0000 |
> 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@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: [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
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| RE: [xsl] Filter out elements that , stephan | Thread | Re: [xsl] Filter out elements that , Andrew Welch |
| [xsl] Re: Using xsl:output in brows, Braumüller, Hans | Date | Re: [xsl] Filter out elements that , Andrew Welch |
| Month |