[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: simple XPath question
Hi Chris,
Yours is a problem that nicely demonstrates why position() can be tricky to use except in very clearly controlled situations. (It's sometimes recommended as an alternative to more expensive operations, but it has its own traps to watch out for.) The function returns the "context position" of the node being processed. This is tricky because the context position is the position of the node among the nodes it is picked up with, when it's picked up, i.e. the "current node list". And what, exactly, the current node list is, is sometimes a bit hard to see -- especially when things like whitespace-only nodes (which are easy not to see) get involved. At 09:47 PM 7/2/01, you wrote: I am trying to work through an example in Khun Yee Fung's XSLT book. It is not giving me the solution he claims it should, but I do not understand why not. This is correct behavior. Each time the country element in your source is selected, it is the first country element among country element children of its parent. So both of them match the expression "child::country[position()=1]" (which is the unabbreviated form of the expression "country[1]"). What seems strange to me is that when I include the line <xsl:copy-of select='position()'/> at the beginning of the template matching country[1], I get a 1 and a 2. This is also correct (though perhaps a bit arguable). Both 'country' elements were selected by the <xsl:apply-templates select="item/country"/> instruction in the template matching the 'warehouse' element. This is short for select="child::item/child::country". Since each is the first 'country' child of its parent 'item', both get position()=1. (The reason I say it's arguable is that I can see someone saying "but isn't the current node list the list of country children of item children"? But I'm not quite willing to dig into the spec this second and hash out why it's not.) I believe I am supposed to get: <storage> <first-country> <country>US</country> </first-country> <country>Canada</country> </storage> I can't speak to Fung's book since I don't have a copy. :-( But a more robust match to do what you want would be <xsl:template match="country[not(preceding::country)]" > or, if you're concerned about performance (since this match will be slow on large documents), you can try <xsl:template match="country[not(preceding::country)[1]]" > which will allow some processors to optimize the test somewhat. Hope that helps, Wendell ====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ====================================================================== 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
|