It's been a little while on this thread, but I thought you might like to know I just published a short article on "//" in XPath/XQuery. It's the fifth and final one in the series on XPath "punctuation": http://developer.marklogic.com/blog/xpath-punctuation-part-5
Evan Lenz Software Developer, Community MarkLogic Corporation From: Evan Lenz <[email protected]<mailto:[email protected]>> Reply-To: General MarkLogic Developer Discussion <[email protected]<mailto:[email protected]>> Date: Thu, 12 May 2011 11:52:40 -0700 To: Mike Sokolov <[email protected]<mailto:[email protected]>>, General MarkLogic Developer Discussion <[email protected]<mailto:[email protected]>> Subject: Re: [MarkLogic Dev General] How To Get The "Content" of An Index? I think most beginners expect .//foo to be short for descendant::foo (which I'm guessing is what you meant), especially since in examples like that they return the exact same results. // is only a gotcha when you start using positional predicates (so be suspicious whenever you see them together without parentheses). Why was it defined this way (as it was originally in XPath 1.0)? I don't think it was to make it easy to "find all the eldest descendant foos" (I like how you put that :-) I think the answer is so that expressions like //@foo would work. //@foo expands to /descendant-or-self::node/@foo, which means "get me each @foo attribute attached to the current element or one of its descendant elements." A clever specification trick. But if I had a time machine, I'd point out the gotcha that would someday trip everyone up and convince the XSL Working Group that users that want to do that are just going to have to type (.|.//*)/@foo if that's what they want. You're right that it's not likely to change. Evan From: Mike Sokolov <[email protected]<mailto:[email protected]>> Date: Thu, 12 May 2011 11:02:50 -0700 To: General MarkLogic Developer Discussion <[email protected]<mailto:[email protected]>> Cc: Evan Lenz <[email protected]<mailto:[email protected]>> Subject: Re: [MarkLogic Dev General] How To Get The "Content" of An Index? I've always been baffled by this interpretation - thanks for explaining. Doesn't it seem as if .//foo *should* mean "descendant-or-self::foo" ? At least that is what every newcomer's interpretation seems to be. I guess one can't change the spec if that's not the case. If it did, then .//foo[1] would do the thing that everybody seems to expect it to, and the parentheses wouldn't be necessary. In any case,this points out another idiom that can be used here, as an alternative to parentheses. I can't help wondering is there some other case that would have been fouled up by this sort of elision? I guess it would become more difficult to find all the eldest descendant foos, but that really does seem like an edge case. -Mike On 05/11/2011 04:16 PM, Evan Lenz wrote: Just to explain why Geert's suggestion to add parentheses around $song-doc//ts:Value works, this doesn't really have anything to do with document vs. sequence order (they're one and the same), but with which sequence(s) the predicate (the part in square brackets) is being applied to. The key is understanding what "//" is short for: "/descendant-or-self::node()/" (.//foo)[1] means "get me all descendant <foo> elements and then return just the first one" (returning a maximum of one node). In this case, the predicate "[1]" applies to the whole (parenthesized) expression to its left. .//foo[1] means "get me every descendant <foo> element that is the first <foo> child of its parent". This expression could return many <foo> elements (which is what you were experiencing with all those <ts:Value> elements). In this case, the predicate "[1]" is tightly bound to "foo" and applies only to the third step of the expression (where the steps are, respectively, ".", "descendant-or-self::node()", and "foo[1]").
_______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
