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 |