XSLT namespace selection (how)?

Q

Queue

I am trying to transform an XML document (google base feed) where it's
root element falls within a namespace. Because of this namespace, my
simplistic XSL transformation doesn't (I'm guessing) match/select the
correct elements.

Can someone please explain the matching/selection (xpath?) syntax for
projecting some of the element's data such as <id> and
<openSearch:totalResults>?

The example google base feed is:

<?xml version='1.0'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:eek:penSearch='http://
a9.com/-/spec/opensearchrss/1.0/' xmlns:gm='http://base.google.com/ns-
metadata/1.0' xmlns:g='http://base.google.com/ns/1.0'
xmlns:batch='http://schemas.google.com/gdata/batch'>
<updated>2007-05-25T18:56:07.358Z</updated>
<openSearch:totalResults>1</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry>
<id>foo1</id>
</entry><entry>
<id>foo2</id>
</entry>
</feed>

And a simplistic XSL attempting to select the <id>:

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:feed='http://www.w3.org/2005/Atom'
version="1.0"<xsl:template match="/">
<xsl:for-each select="feed:entry">
<xsl:value-of select="id" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>


Much appreciated. Thanks,
 
B

Bjoern Hoehrmann

* Queue wrote in comp.text.xml:
<xsl:template match="/">
<xsl:for-each select="feed:entry">
<xsl:value-of select="id" />

You have two errors here. The first is that feed:entry is not a child of
the root node, they are children of the feed:feed element. So you would
have to say e.g.

xsl:for-each select = 'feed:feed/feed:entry'

This is unlikely the best way, but this would work. Further, the <id>
element is also in the http://www.w3.org/2005/Atom namespace, so you
have to specify the prefix in the value-of aswell, i.e.

xsl:value-of select = 'feed:id'

The rule is quite simple, if what you want to refer to is in a namespace
you have to declare a prefix for the namespace and always specify the
prefix.
 
Q

Queue

xsl:for-each select = 'feed:feed/feed:entry'
xsl:value-of select = 'feed:id'

Great, this works. Thank you. Thus for any element declared within a
namespace, in the corresponding XSL all elements within that hierarchy
must be prefixed?

What about the case in the example

<openSearch:totalResults>1</openSearch:totalResults>

Which is contained within the <feed> element (prefixed). I am sure I
can't simply do select="feed:eek:penSearch:totalResults". What about
nested elements within namespaces?

Thank you again,
 
J

Joseph Kesselman

Queue said:
>Thus for any element declared within a
>namespace, in the corresponding XSL all elements within that hierarchy
>must be prefixed?

No. To match a namespaced name at any given point in an XPath, the path
must use a prefixed name at that point where the prefix is bound to the
correct namespace. So to match
<openSearch:totalResults>1</openSearch:totalResults>

directly, you would use:
select="opensearch:totalResults"

Or, if you needed to specify multiple steps to reach it, you would use
something like:
select="feed:feed/feed:entry/opensearch:totalResults"
 
X

xailor

select="opensearch:totalResults"
select="feed:feed/feed:entry/opensearch:totalResults"

I just tried this from that XML example in the XSL below but I receive
no selection of the data? Shouldn't the whole openSearch prefix be
prefixed itself? Thanks for all the newbie help.

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:eek:penSearch='http://a9.com/-/spec/opensearchrss/1.0/'
xmlns:gm='http://base.google.com/ns-metadata/1.0'
xmlns:g='http://base.google.com/ns/1.0'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:feed='http://www.w3.org/2005/Atom'
version="1.0"<xsl:template match="/">
<div>
<span>total1=<xsl:value-of select="openSearch:totalResults"/>
</span>
<span>total2= <xsl:value-of select="feed:feed/feed:entry/
openSearch:totalResults"/> </span>
<xsl:for-each select="feed:feed/feed:entry">
<pre>
<xsl:value-of select="feed:id" />
</pre>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
 
B

Bjoern Hoehrmann

* xailor wrote in comp.text.xml:
I just tried this from that XML example in the XSL below but I receive
no selection of the data? Shouldn't the whole openSearch prefix be
prefixed itself? Thanks for all the newbie help.

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:eek:penSearch='http://a9.com/-/spec/opensearchrss/1.0/'
xmlns:gm='http://base.google.com/ns-metadata/1.0'
xmlns:g='http://base.google.com/ns/1.0'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:feed='http://www.w3.org/2005/Atom'
version="1.0"
<xsl:template match="/">
<div>
<span>total1=<xsl:value-of select="openSearch:totalResults"/>

Again, here the context node is the document node which usually has a
single child node, the root element of the document, the <feed> element
in your example. 'openSearch:totalResults' matches all openSearch:
totalResults elements that are a child of the context node, but there
is no such child.
<span>total2= <xsl:value-of select="feed:feed/feed:entry/
openSearch:totalResults"/> </span>

This would only match the first openSearch:totalResults element, you
likely want this for each entry.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top