[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] XSLT 1.0 Namespace Help

Subject: Re: [xsl] XSLT 1.0 Namespace Help
From: "Wendell Piez wapiez@xxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 25 Aug 2014 19:32:41 -0000

Hi Bridger,

I missed that you were limited to XSLT 1.0. How sad for you!

Yes, when using XSLT 1.0, one is limited to option D, or the (usually
preferred) D1 option of declaring all the namespaces you will need at
the top of the stylesheet.

Since it is probably the least obvious of the four options I
suggested, you can see part of why namespaces are so widely hated by
those who have tried to teach themselves XSLT 1.0 without prior XML
experience. (This red herring haunts XSLT's reputation to this day, if
you will forgive the idea of being haunted by a fish.)

In XSLT 1.0, you can save yourself trouble by following the rule that
if names are in a namespace, you assign a prefix for addressing it --
don't use unprefixed names in XPath 1.0 to address names in a
namespace. This is because the only way of binding such names in XSLT
1.0 is with xmlns="..." -- the default namespace -- and guess what,
voila, you have just declared that all unprefixed names in your XSLT
where this declaration is in scope (not just in your XPath) are in
this namespace! Which is often not what's wanted.

So declaring prefixes for any elements we're going to need to address
by name becomes part of XSLT 1.0 housekeeping.

In XSLT 2.0 since we have xpath-default-namespace, things don't have
to be so rigid.


On Mon, Aug 25, 2014 at 2:02 PM, Bridger Dyson-Smith
bdysonsmith@xxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi Wendell,
> Thank you for the suggestions.
> On Mon, Aug 25, 2014 at 1:36 PM, Wendell Piez wapiez@xxxxxxxxxxxxxxx
> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>> Hi Bridger,
>> Please don't do this:
>> On Mon, Aug 25, 2014 at 10:36 AM, Bridger Dyson-Smith
>> bdysonsmith@xxxxxxxxx wrote:
>> > <xsl:for-each
>> >
>> > select="$queryDoc/*[local-name()='sparql']/*[local-name()='results']/*[local-name()='result']/*[local-name()='collection']/@uri">
>> Instead of asking for them by name, you are effectively asking the
>> processor to look at all your elements, testing each of them by
>> comparing (part of) its name to a literal value.  There are several
>> reasons why this is not as good an idea as it may seem.
>> If you really wish to select elements irrespective of namespace, this is
>> better:
>> (A) select="$queryDoc/*:sparql/*:results/*:result]/*:collection/@uri"
>> or perhaps
>> (B) select="$queryDoc//*:collection/@uri"
> I had tried both of these variations but Saxon (v6.5.5) kept giving me
> "Invalid character ( : ) in expression ...".
>> or maybe
>> (C) select="$queryDoc//collection/@uri"
>> xpath-default-namespace="http://www.w3.org/2001/sw/DataAccess/rf1/result"
>> (referring to the namespace of the element in the source data)
> For posterity, isn't xpath-default-namespace a 2.0 feature only?
>> or
>> (D) select="$queryDoc//rf1:collection/@uri"
>> xmlns:rf1="http://www.w3.org/2001/sw/DataAccess/rf1/result"
> This is the ticket! That's a very handy thing to know -- I did not know that
> you could add in a namespace declaration like that!
>> or (C) or (D), except with the declaration of a prefix for the
>> namespace, or the instruction to the XSLT engine to default to it,
>> promoted onto an ancestor element such as the xsl:stylesheet element.
>> There are a number of reasons to avoid the cumbersome
>> *[local-name()=$name] approach to finding elements. Among other
>> things, it is asking the machine how to do something (find elements by
>> their names) that it has already been programmed to do. This means,
>> for example, it is apt to be significantly slower in execution than
>> doing it the "right" way (using XPath name tests, not filters).
>> It is like going to the cheese shop, and telling the cheese man how to
>> tell the difference between Stilton and Double Gloucester. He already
>> knows the difference, and only needs you to tell him which cheese you
>> want.
>> So (in general), ask for things by name, so //*:collection if you
>> *really* don't know the namespace. If you do know the namespace, use
>> it.
>> > and now it's working.
>> Yes but only sort of!
>> > Apologies for the noise.
>> Please don't apologize for asking questions on topic! (You have
>> presented an extremely common solecism in XSLT.)
>> Cheers, Wendell
>> --
>> Wendell Piez | http://www.wendellpiez.com
>> XML | XSLT | electronic publishing
>> Eat Your Vegetables
>> _____oo_________o_o___ooooo____ooooooo_^
> Thank you for the suggestions and the added improvements.
> Best,
> Bridger
> XSL-List info and archive
> EasyUnsubscribe (by email)

Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables

Current Thread