Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Namespaces in use?

0 views
Skip to first unread message

Robert Rolls

unread,
Jan 30, 2004, 10:22:39 PM1/30/04
to
I've loaded an xml document and I need to retrieve the list of namespace
decalrations within the document.

Any help greatly appreciated.
Robert.


Janwillem Borleffs

unread,
Jan 31, 2004, 6:12:33 AM1/31/04
to
Robert Rolls wrote:
> I've loaded an xml document and I need to retrieve the list of
> namespace decalrations within the document.
>

XML:

<?xml version="1.0"?>
<h:html xmlns:xdc="http://www.xml.com/books"
xmlns:h="http://www.w3.org/HTML/1998/html4">
<h:head><h:title>Book Review</h:title></h:head>
<h:body>
<xdc:bookreview>
<xdc:title>XML: A Primer</xdc:title>
<h:table>
<h:tr align="center">
<h:td>Author</h:td><h:td>Price</h:td>
<h:td>Pages</h:td><h:td>Date</h:td></h:tr>
<h:tr align="left">
<h:td><xdc:author>Simon St. Laurent</xdc:author></h:td>
<h:td><xdc:price>31.98</xdc:price></h:td>
<h:td><xdc:pages>352</xdc:pages></h:td>
<h:td><xdc:date>1998/01</xdc:date></h:td>
</h:tr>
</h:table>
</xdc:bookreview>
</h:body>
</h:html>


XSLT:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />
<xsl:key name="prefix" match="*" use="substring-before(name(),':')" />

<xsl:template match="/">
<xsl:for-each select="
descendant-or-self::*[
namespace-uri()
and
generate-id() =
generate-id(key('prefix',substring-before(name(),':')))
]">
<xsl:value-of select="
concat(
'NS Prefix: ',
substring-before(name(),':'),
', URI: ',
namespace-uri(),
'&#10;'
)" />
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>


HTH;
JW

Dimitre Novatchev

unread,
Jan 31, 2004, 8:24:01 AM1/31/04
to

"Janwillem Borleffs" <j...@jwscripts.com> wrote in message
news:401b8d9b$0$79385$18b...@news.wanadoo.nl...


Unfortunately the above transformation does not produce correct results.

For example, let's have the following source.xml:

<test1>
<foo:test xmlns:foo="bigrabbit" foo:gg="3"
foo:hh="4">
<bar xmlns:foo="littlerabbit"
foo:squid="fish"/>
<baz xmlns:hi="anothernamespace"
hi:attr="value" />
</foo:test>
<p1:anc1 xmlns:p1="ns1">
<p1:anc2 xmlns:p1="ns2">
<p1:anc3 xmlns:p1="ns1" />
</p1:anc2>
</p1:anc1>
</test1>

The result of applying the above transformation to this xml document is:

NS Prefix: foo, URI: bigrabbit
NS Prefix: p1, URI: ns1

It does not produce anything for:

The xml namespace: xmlns:xml="http://www.w3.org/XML/1998/namespace"

xmlns:foo="littlerabbit"

xmlns:hi="anothernamespace"

xmlns:p1="ns2


Here I provide a transformation, which produces correct results:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext"
>

<xsl:key name="kdistNS" match="namespace" use="."/>

<xsl:template match="/">
<xsl:variable name="vrtfNamespaces">
<xsl:apply-templates select="*">
<xsl:with-param name="pNamespaces" select="/.."/>
</xsl:apply-templates>
</xsl:variable>

<xsl:for-each
select="ext:node-set($vrtfNamespaces)/*
[generate-id()
=
generate-id(key('kdistNS', .)[1])
]">
<xsl:value-of
select="concat('&#xA;', substring-before(.,'|'),
': ', substring-after(.,'|')


)"/>
</xsl:for-each>
</xsl:template>

<xsl:template match="*">
<xsl:for-each select=" namespace::*">
<namespace>
<xsl:value-of select="concat(name(), '|', .)"/>
</namespace>
</xsl:for-each>

<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>

When this transformation is applied against the same source.xml:

<test1>
<foo:test xmlns:foo="bigrabbit" foo:gg="3"
foo:hh="4">
<bar xmlns:foo="littlerabbit"
foo:squid="fish"/>
<baz xmlns:hi="anothernamespace"
hi:attr="value" />
</foo:test>
<p1:anc1 xmlns:p1="ns1">
<p1:anc2 xmlns:p1="ns2">
<p1:anc3 xmlns:p1="ns1" />
</p1:anc2>
</p1:anc1>
</test1>

the correct result is produced:

xml: http://www.w3.org/XML/1998/namespace
foo: bigrabbit
foo: littlerabbit
hi: anothernamespace
p1: ns1
p1: ns2


Hope this helped.

Cheers,

Dimitre Novatchev [XML MVP]
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html


Janwillem Borleffs

unread,
Jan 31, 2004, 8:57:11 AM1/31/04
to
Dimitre Novatchev wrote:
> Here I provide a transformation, which produces correct results:
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:ext="http://exslt.org/common"
> exclude-result-prefixes="ext"
> >
>

Nice example, only, you did forget to mention that exslt is an additional
library and not supported by default by parsers like msxml and sablotron.

I'm also wondering if the XML that you mentioned will happen in real life.
The re-usage of ns prefixes looks very dirty.


JW

Dimitre Novatchev

unread,
Jan 31, 2004, 10:33:49 AM1/31/04
to
> Nice example, only, you did forget to mention that exslt is an additional
> library and not supported by default by parsers like msxml and sablotron.

EXSLT is not something unknown to anyone reading the xml pages of MSDN.
EXSLT has an open-source implementation -- both for dotNet:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml11172003.asp

and for MSXML4 (The Sets and Common modules):

http://www.xml.com/pub/a/2003/08/06/exslt.html


And in the case that someone has not installed one of these, then there's
the Microsoft-provided msxsl:node-set() extension function where the "msxsl"
(or whatever) prefix should be bound to the
"urn:schemas-microsoft-com:xslt"
URI

When I'm using EXSLT I do this intentionally with the goal that my snippets
should be portable across as many different XSLT processors as possible.

For example, on my computer they run without modifications with:
MSXML4,
dotNet XslTransform,
Saxon 6.5.3,
Saxon 7.8,
XalanJ 2.4.1,
JD,
4xslt

... just to name a few.

>
> I'm also wondering if the XML that you mentioned will happen in real life.
> The re-usage of ns prefixes looks very dirty.

Why, imagine that some code is assembled from multiple sources (e.g. by copy
and paste)...

When one expects real life to be nice then the pain of understanding the
reality may be considerably hurting. And this is serious. For example, in
some countries they emphasize on "defensive driving" when teaching people to
drive.

But even if we put aside those "dirty" cases, your transformation will have
additional problems -- e.g. namespaces that are declared, but not used. What
the original poster wanted was:

"I need to retrieve the list of namespace decalrations within the
document."

Han

unread,
Feb 1, 2004, 8:40:27 PM2/1/04
to
If you mean DOM, you may want namespace axix. e.g.

for each n in xml.selectNodes("//namespace::*")
msgbox n.text
next

You may need to cook the code for you need.

--
Pohwan Han, Microsoft MVP, ASP/ASP.Net, Korea
Have a nice day.

"Robert Rolls" <rr...@yahoo.com> wrote in message
news:enTDDm65...@TK2MSFTNGP10.phx.gbl...

0 new messages