[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: Fwd: complex XPATH test
Adam and Wendell, Here's the solution I came up with, which raised a question or two itself. <xsl:template match="br"> <xsl:variable name="containing-block" select="ancestor::p[1]"/> <!-- use '1' for the predicate since ancestor axis returns reverse document order --> <xsl:variable name="curr" select="current()"/> <xsl:variable name="currPos"> <xsl:for-each select="$containing-block/descendant::node()"> <xsl:if test="count(.|$curr) = count(.)"> <xsl:value-of select="position()"/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- $containing-block/descendant::node()[.=current()]/position() (doesn't work)--> <xsl:if test="$containing-block/descendant::node()[position() > $currPos]"> <br/> </xsl:if> </xsl:template> For starters, there has to be a better way of returning the position of a node within a node set than what I used here (the for-each block). Anyone have any ideas? I tried <xsl:variable name="currPos" select="$containing-block/descendant::node()[.=current()]/position()"/> knowing it wouldn't work (from previous posts to the list, etc.) and I wasn't disappointed. So the question I have is: How do you return the position of a node in a node set given the node and the node set, so that the position can be used in a comparison or a variable? Second, why is it that ".=$curr" tests the value of each against each other, rather than a 'node id' or something? Wouldn't it make sense for that to actually check that the nodes are equivalent since if I wanted to check their string values I could do "string(.)=string($curr)" but I can't do the reverse. (ie. "node(.)=node($curr)" or something). I'm I overlooking something here? This is getting long, maybe it's time for a new thread. <g> Back to Adam's original problem... this will output the <br/> if there are any nodes further down the tree from the block element than the <br/> tag is, so it may or may not give you the results you want. For instance: <p>this is a little bit of text<br /><br /></p> would return <p>this is a little bit of text<br /></p> also, <p>this is a little bit of text<br /> </p> would return <p>this is a little bit of text<br /> </p> if you didn't strip the whitespace ahead of time. I'm with Wendell. I'd still like to see a slick solution. -Nate naustin@xxxxxxxxxx > Date: Mon, 16 Jul 2001 19:03:24 -0400 > From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> > Subject: Re: complex XPATH test > > Adam, > > <xsl:template match="br"> > <!-- 1st, retrieve the block ancestor you're worried about --> > <xsl:variable name="containing-block" > select="(ancestor::p|ancestor::li|ancestor::blockquote)[last()]"/> > <!-- (you'll have to extend that list to include all the possible > blocks) --> > <!-- now, figure out what text nodes are actually > following inside the > block --> > <xsl:variable name="text-following"> > <xsl:for-each > select="$containing-block//text()[.=current()/following::text()"> > <xsl:value-of select="."/> > </xsl:for-each> > <!-- now, include the br if there's anything there besides > white space --> > <xsl:if test="normalize-space($text-following)"> > <xsl:copy-of/> > </xsl:if> > </xsl:template> > > (untested) > > It's slow and painful, but then those <br> elements are painful too. > > What do you think? I'd like to see a slick solution, too.... > > Cheers, > Wendell > > At 06:11 PM 7/16/01, you wrote: > >Hey guys, > > > >I'm working on an transform that will take well formed HTML > and convert it > >into a different prose schema (NITF). > > > >I'm trying to do some intelligent filtering of valid, but > meaningless HTML > >markup (the DHTML Edit control will occasionally give me > stuff I'm not too > >happy aobut). > > > >If I have a <br> tag inside a block element, I only want to > deal with it if > >its not the last br tag. An example > > > >I care about the br in : > ><p> this is some text<br /> > >here is some more</p> > > > >but not in: > ><p>this is a little bit of text<br /></p> > > > >My original test was > ><xsl:template match="br"> > > <xsl:if test="count(following-sibling::node()) > 0"> > > <br/> > > </xsl:if> > ></xsl:template> > > > >but I ran into a problem with the following: > > > ><p><strong>this is some bolded text<br/></strong>Some more text</p> > > > >since the br was getting ignored. > > > >What I want to do is test that the context node is not the > last child of the > >context node's ancestor block node. Its also not the case > that immediate > >parent of that block node will be <body> since <li> is a > block node and is a > >child of <ol> or <ul>. > > > >Any thougths? > > > >Adam van den Hoven > >Internet Software Developer > >Blue Zone > >tel. 604 685 4310 ext. 260 > >fax 604 685 4391 > > > > > Blue Zone makes you interactive. http://www.bluezone.net/ > > > > > > > > > > Date: Mon, 16 Jul 2001 19:11:45 -0400 > From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> > Subject: Fwd: Re: complex XPATH test > > Oops, I realized there's one bug... the equality test > > $containing-block//text()[.=current()/following::text()] > > (I also note typo in my code, missing ']') > > isn't going to do the trick. You're going to need some kind of > intersection. Like > > $containing-block//text()[count(.|current()/following::text()) > =count(current()/following::text())] > > which will really be horrible and slow, even if you put > current()/following::text(), and its count, into a variable.... > > Anyone else? Heh, > Wendell > > > >Date: Mon, 16 Jul 2001 19:03:24 -0400 > >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > >From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> > >Subject: Re: complex XPATH test > > > >Adam, > > > ><xsl:template match="br"> > > <!-- 1st, retrieve the block ancestor you're worried about --> > > <xsl:variable name="containing-block" > > select="(ancestor::p|ancestor::li|ancestor::blockquote)[last()]"/> > > <!-- (you'll have to extend that list to include all the possible > > blocks) --> > > <!-- now, figure out what text nodes are actually > following inside the > > block --> > > <xsl:variable name="text-following"> > > <xsl:for-each > > select="$containing-block//text()[.=current()/following::text()"> > > <xsl:value-of select="."/> > > </xsl:for-each> > > <!-- now, include the br if there's anything there > besides white space --> > > <xsl:if test="normalize-space($text-following)"> > > <xsl:copy-of/> > > </xsl:if> > ></xsl:template> > > > >(untested) > > > >It's slow and painful, but then those <br> elements are painful too. > > > >What do you think? I'd like to see a slick solution, too.... XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|