XSLT makes life a bit easier in this regard by making a distinction between the default *output* namespace (using xmlns) and the default *XPath* namespace (using xpath-default-namespace). So it's much less dangerous (and thus more useful) to use a default element namespace (for input or output) in XSLT. You can also redefine either at different parts of the stylesheet, but since as Damon points out for XQuery, the scoping of a default namespace is lexical/inflexible, so I try to use no more than one of each (input and output) per XSLT module (at the top).
Evan On 5/11/11 11:00 AM, "Damon Feldman" <[email protected]> wrote: >Will, > >Those default namespaces are based on static context, so if you break >your $config access out into a function you can avoid the default >namespace that is throwing you off. > >It's a tricky bit in xquery 1.0. Empty namespaces can't be explicitly >declared inside a syntactic context where a default namespace already >exists. > >Yours, >Damon > >-----Original Message----- >From: [email protected] >[mailto:[email protected]] On Behalf Of Will >Thompson >Sent: Wednesday, May 11, 2011 10:09 AM >To: General MarkLogic Developer Discussion >Subject: Re: [MarkLogic Dev General] Node selector xpath not working > >Jason and Evan, > >You were both right about the namespace issue, but it wasn't from the >document. It was the context of my xquery - building part of an options >node for Search API, and I didn't realize the namespace would still be >implicit when querying with doc(). > >E.g.: > >declare function local:get-options(){ ><options xmlns="http://marklogic.com/appservices/search"> >... > <additional-query>{ > ... > let $config-info := doc("/config/config-file.xml")//some-element > ... > }</additional-query> >... ></options> > >So I assume the problem is that the xpath evaluates to >//search:some-element -- Is there a way to query the null namespace >without doing //*:some-element (since, as Jason mentioned, that does not >use indexes)? Would Evan's xpath be indexed?: //*[node-name(.) eq >fn:QName("","some-element")] > >The only thing I can think of is to go out of the scope of the namespace >by calling an outside function, like: > >let $config-info := local:get-config-info() > > >Thanks for your help, guys, > >Will > > >-----Original Message----- >From: [email protected] >[mailto:[email protected]] On Behalf Of Evan Lenz >Sent: Wednesday, May 11, 2011 12:35 AM >To: General MarkLogic Developer Discussion >Subject: Re: [MarkLogic Dev General] Node selector xpath not working > >Actually, they're not the same thing. The name() function returns the >lexical QName of the element as it appears in the source document (which >might not include a prefix, even if the element is namespace-qualified). >It's better to use the node-name() function, which returns an actual >xs:QName value encapsulating the element's namespace URI and local name. > >If [name() eq "some-element"] returns true, all that tells you is that the >element in the source document doesn't use a prefix; it doesn't say one >way or the other whether it uses a namespace, or what the namespace is if >it does. It's generally a bad idea to use the name() function for this, >because adding or changing a prefix in the source document would suddenly >break your code, and prefixes are supposed to be considered insignificant. >In general, you should avoid using the name() function and use node-name() >instead (or a combination of local-name() and namespace-uri()). >(Incidentally, //node()[name() eq "some-element"] will also select ><?some-element?> PIs, but now I'm getting academic...) > >Try this instead. In the same query context, the following expression >should always return the same results as //some-element (if more slowly): > >//*[node-name(.) eq xs:QName("some-element")] > >My guess is that your source document has declared a default namespace, >which means you'll need to declare the same namespace in your XQuery. Look >in the source document to see what the namespace is (xmlns declaration, >typically at the top but could be on any ancestor or the element itself). >And then declare the same namespace in your XQuery (using any prefix): > >declare namespace x="http://yournamespace.com"; >//x:some-element > >I'm not sure why you're getting different results in the two contexts >(default namespace in effect in one of the two query contexts?), but maybe >this distinction will help you track down the issue. > >By the way, behind-the-scenes indexing magic can affect how fast one XPath >expression is versus another, but it should never affect the actual >results you get. This looks like a typical namespace gotcha, but I eagerly >await what you find out. :-) > >Evan Lenz >Software Developer, Community >MarkLogic Corporation > > >On 5/10/11 4:15 PM, "Will Thompson" <[email protected]> wrote: > >>Damon, >> >>There is no default namespace in this module - I double-checked using the >>commands you suggested, and the database name is the same as the one >>selected in CQ, and it logs "NS=" for the element I'm trying to select. >> >>Since these two xpaths should evaluate to exactly the same thing: >> >>//some-element >>//node()[name(.)="some-element"] >> >>I'm very surprised that one works and the other doesn't. I know there is >>some behind the scenes ML index magic that I don't understand, but if >>that were the issue, wouldn't it also break in CQ? >> >>Best, >> >>Will >> >> >>-----Original Message----- >>From: [email protected] >>[mailto:[email protected]] On Behalf Of Damon >>Feldman >>Sent: Tuesday, May 10, 2011 5:50 PM >>To: General MarkLogic Developer Discussion >>Subject: Re: [MarkLogic Dev General] Node selector xpath not working >> >>Will, >> >>Is there a default namespace at play? You can check by adding: >> >>xdmp:log(text{"NS=", namespace-uri(<cts:elem/>)}) >> >>to your module. Similarly, you can check the database by logging >> >>xdmp:database-name(xdmp:database()) >> >>to ensure the app server is looking at the data you think it is. >> >>Yours, >>Damon >> >>-----Original Message----- >>From: [email protected] >>[mailto:[email protected]] On Behalf Of Will >>Thompson >>Sent: Tuesday, May 10, 2011 3:05 PM >>To: General MarkLogic Developer Discussion >>Subject: [MarkLogic Dev General] Node selector xpath not working >> >>doc("/config/config-file.xml")//some-element >> >>CQ returns the expected elements, but the same query executed through the >>app server returns empty. Same content source. This is how I had to >>work around it in my app: >> >>doc("/config/config-file.xml")//node()[name(.)="some-element"] >> >>I don't see why one would work and not the other. It's not a show >>stopper, but it's definitely bizarre. Any ideas about what could be >>going on? >> >>Thanks, >> >>Will >>_______________________________________________ >>General mailing list >>[email protected] >>http://developer.marklogic.com/mailman/listinfo/general >>_______________________________________________ >>General mailing list >>[email protected] >>http://developer.marklogic.com/mailman/listinfo/general >>_______________________________________________ >>General mailing list >>[email protected] >>http://developer.marklogic.com/mailman/listinfo/general > >_______________________________________________ >General mailing list >[email protected] >http://developer.marklogic.com/mailman/listinfo/general >_______________________________________________ >General mailing list >[email protected] >http://developer.marklogic.com/mailman/listinfo/general >_______________________________________________ >General mailing list >[email protected] >http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
