Discussion:
Matching all elements in a namespace
Kjetil Kjernsmo
2004-02-07 20:40:20 UTC
Permalink
Hello World!

I just subscribed, as I heard this is _the_ list for XSLT "user"
questions? :-)

My question feels like a common requirement, and therefore a FAQ, but I
really can't find the answer...

To take an example, my XML contains a few XHTML elements, and I figured
I'll just declare them in the XHTML namespace, and then copy-of all
elements in this namespace to the result document, with the namespace
declaration and all... (later, I want to do similar things with other
namespaces).

So, the obvious thing felt like something like...:
<xsl:template match="namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict'">
<xsl:copy-of select="."/>
</xsl:template>

...and I've tried numerous variations over this theme over the past
couple of weeks, but it doesn't "work".

I'm developing on the top of AxKit, so I'm using XML::LibXSLT and
Apache::AxKit::Language::LibXSLT to do the work. I could use Sablotron
also, however.

Also complicating matters, is that this is just a part of a pipeline,
starting with AxKit's XSP page. So, I am to a certain extent at the
mercy of what AxKit will give me, which again implies that whatever I
do should work if I have a xmlns attribute on the root element, and
shorthand prefixes on the rest, or a xmlns attribute on whatever
elements there are in that namespace, or, well, you get the idea... :-)

I figured it should be most robust to match on the namespace-uri rather
than a prefix shorthand, since the latter can be chosen rather
arbitrarily by an author, whereas the namespace-uri has a more clearly
defined meaning. Is this reasoning sound?

BTW, if anybody's interested (ok, it is a shameless plug), the
application I'm developing I've called TABOO, I'm introducing a bit
more abstraction and OO design, and the first thing I'm building is a
news-site. I've released something allready:
http://www.kjetil.kjernsmo.net/software/TABOO/

Cheers,

Kjetil
--
Kjetil Kjernsmo
Astrophysicist/IT Consultant/Skeptic/Ski-orienteer/Orienteer/Mountaineer
***@kjernsmo.net ***@skepsis.no ***@learn-orienteering.org
Homepage: http://www.kjetil.kjernsmo.net/ OpenPGP KeyID: 6A6A0BBC


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
J.Pietschmann
2004-02-07 21:01:30 UTC
Permalink
Post by Kjetil Kjernsmo
<xsl:template match="namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict'">
<xsl:copy-of select="."/>
</xsl:template>
...and I've tried numerous variations over this theme over the past
couple of weeks, but it doesn't "work".
You can only match on match pattern, not arbitrary XPath
expressions. Try
<xsl:template match=*["namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict']">

J.Pietschmann

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2004-02-07 21:28:48 UTC
Permalink
As you say this is a faq, the link to the faq is on the page mentioned
at the bottom of every message on this list.


<xsl:template match="namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict'">
<xsl:copy-of select="."/>
</xsl:template>


several things wrong,
firstly the match attribute has to take a Pattern, ie a restricted form
of Xpath exprssion that would select nodes. You have an = expression so
its a boolean valued expression just evaluating to true or false so is a
syntax error.

secondly that is not the xhtml namespace
you want'http://www.w3.org/1999/xhtml

so you want to put
xmlns:h="http://www.w3.org/1999/xhtml"
on your xsl:stylesheet and then have

match="h:*"

that matches everything in that namespace (whatever prefix or non-prefix
they have in the source file).

David
--
http://www.dcarlisle.demon.co.uk/matthew


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2004-02-07 21:42:11 UTC
Permalink
Post by Kjetil Kjernsmo
<xsl:template match="namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict'">
<xsl:copy-of select="."/>
</xsl:template>
...and I've tried numerous variations over this theme over the past
couple of weeks, but it doesn't "work".
When the obvious thing doesn't work, the time has come to read the spec.

You can match all elements in a namespace by writing

<xsl:template
match="*[namespace-uri()='http://www.w3.org/TR/xhtml1/strict']"

or by

<xsl:template match="xhtml:*"
xmlns:xhtml="http://www.w3.org/TR/xhtml1/strict">

Note that this doesn't require the elements in the source document to
use the same prefix.

Whether <xsl:copy-of> is really what you want to do inside the template
rather depends on details of the requirement, which you haven't
explained very fully.

Michael Kay


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Kjetil Kjernsmo
2004-02-07 22:39:45 UTC
Permalink
Post by Michael Kay
Post by Kjetil Kjernsmo
<xsl:template match="namespace-uri() =
'http://www.w3.org/TR/xhtml1/strict'">
<xsl:copy-of select="."/>
</xsl:template>
...and I've tried numerous variations over this theme over the past
couple of weeks, but it doesn't "work".
When the obvious thing doesn't work, the time has come to read the spec.
Uhm, well, yeah, I know. Sort of did that... And I often enjoy reading
specs. And I have this big book. But you know, when you're confused
from the outset, details often slip by...
Post by Michael Kay
You can match all elements in a namespace by writing
<xsl:template
match="*[namespace-uri()='http://www.w3.org/TR/xhtml1/strict']"
Aha, pling, that makes sense!
Post by Michael Kay
or by
<xsl:template match="xhtml:*"
xmlns:xhtml="http://www.w3.org/TR/xhtml1/strict">
Right. OK, when you say that, some points that were unclear from the faq
(matching namespaces in source document), makes a whole lot more sense
in light of this.
Post by Michael Kay
Whether <xsl:copy-of> is really what you want to do inside the
template rather depends on details of the requirement, which you
haven't explained very fully.
Probably because the requirements are not very clear to me at this
point... :-) I'm having a steep learning curve... I didn't choose XSLT
because I knew how to write it, but because it looked like an
interesting approach. So your help is highly appreciated. I'll try to
ask more intelligently the next time! :-)

Thanks a lot, I'll try these suggestions out tomorrow!

Best,

Kjetil
--
Kjetil Kjernsmo
Astrophysicist/IT Consultant/Skeptic/Ski-orienteer/Orienteer/Mountaineer
***@kjernsmo.net ***@skepsis.no ***@learn-orienteering.org
Homepage: http://www.kjetil.kjernsmo.net/ OpenPGP KeyID: 6A6A0BBC


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Askild Aaberg Olsen
2004-02-07 21:48:25 UTC
Permalink
Post by Kjetil Kjernsmo
I figured it should be most robust to match on the
namespace-uri rather
than a prefix shorthand, since the latter can be chosen rather
arbitrarily by an author, whereas the namespace-uri has a
more clearly
defined meaning. Is this reasoning sound?
No. The prefix shorthand is just that; a shorthand for the actual value.
If you declare
<xyz:anyelement xmlns:xyz="http://www.zyz.com"/>

in the source XML, you can still match
<xsl:template match="foo:anyelement" xmlns:foo="http://www.zyz.com"/>

in your XSLT, even though the prefixes differ.

What happens is that the prefix are expanded during processing, something
like this
<{http://www.zyz.com}:anyelement/> in the XML

and
<xsl:template match="{http://www.zyz.com}:anyelement"/> in the XSLT.

Askild Aaberg Olsen


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Continue reading on narkive:
Loading...