Re: Specify/determine element's "logical" parent
> > <xsl:value-of select="key( 'ids', (@parentid|../@id)[last() > > ])/@id" /> > > > > I think this says to look up the element pointed to by the key @parentid if it > is defined, ../@id otherwise, but I am not sure I understand the [last()] - > does that mean that if both parentid and ../@id are defined, ../@id will be > used (in which case I want the reverse, first()? or is this just defensive > programming, habit or something else? XPath is an expression based language in which (pretty much always) any expression can be used anywhere, and it has the same meaning. Especially in the area of conditionals it's often easy to fall in to the trap of giving the same operator different _readings_ in different contexts (eg often its helpful to read | as "or" but it is really set union and different from the boolean or which is "or" in XPath). Which ramble is just a long way of saying that to understand a long XPath you can always read it from the inside out. @parentid selects the node set of nodes matching that, which is a set of 0 or 1 attribute nodes (depending on whether the current element has a parentid) ../@id selects the node set of nodes matching that, which is a set of 0 or 1 attribute nodes (depending on whether the parent of the current element has an id) | is set union, so (@parentid|../@id) is the node set of 0 1 or 2 nodes consisting of at most one id node from the patrent and one parentid from here. In the case that there are two nodes in this set you want (or at least I thought you wanted) the parentid from the current node. In document order the attributes of a parent come before the current element which comes before the current elements attributes so if if this node set does have two nodes, @parentid is the last of them so (@parentid|../@id)[last()] last() returns a number, the position of teh last node in document order (ie its the cardinality of the set) If you use a number in a filter predicate it is short for (@parentid|../@id)[position()=last()] The predicate position()=last() is true just for the last node in document order and false for all other nodes in the set, so this is a node set of 0 or 1 nodes consisting of an @parentid if there is one and a ../@id otherwise. key( 'ids', (@parentid|../@id)[last()]) looks up the value of that attribute node as a key value in the 'ids' key and returns the node (or nodes) that matches (if there is one). the key was defined by xsl:key to match *[@id] that is, any element taht has an id attribute, so an element node will be returned. key( 'ids', (@parentid|../@id)[last()> ])/@id and that selects teh id attribute of that element node. > I had expected the system (IE) to throw an error in this undefined case, but > it recovers (somewhat randomly) I guess. It's not random, it takes the last in the stylesheet, that is teh specified optional recovery acyion in the XSLt spec. A system built in a browser like IE typically takes every allowed possibility to avoid making run time errors, that being the way of life in browser land. A command line system like saxon is much better for debugging it gives lots of helpful warnings, and in particular has a three way switch that lets you choose whether errors that teh XSLt spec says are recoverable are 0) silently ignored and the recovery actiojn taken 1) warning given and recovery action taken 2) stop with a message and fatal error David ________________________________________________________________________ This e-mail has been scanned for all viruses by Star. The service is powered by MessageLabs. For more information on a proactive anti-virus service working around the clock, around the globe, visit: http://www.star.net.uk ________________________________________________________________________
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