Re: [xsl] building namespaces

Subject: Re: [xsl] building namespaces
From: Mike Brown <mike@xxxxxxxx>
Date: Mon, 8 Apr 2002 04:36:22 -0600 (MDT)
Jarkko.Moilanen@xxxxxx wrote:
> Few small questions about namespaces: 
> 1. What do they actually look like?
> 2. It must be part of some document, so in what format? 
> 3. A small example would be great.

The name of an element and the name of an attribute is a "name".

Sometimes you want to distinguish between two names that are the
same but that have different meanings and that come from different
contexts. Example: the 'title' elements in this fragment:

  <info>
    <book>
      <title>Moby Dick</title>
      <author>Herman Melville</author>
    </book>
    <contact>
      <name>Jane Doe</name>
      <title>Editor-In-Chief</title>
    </contact>
  </info>

Namespaces give you a way to expand each name into a pair of strings: one
string is the local name ('title'), and one is the namespace identifier. A
namespace identifier always takes the form of URI.

There doesn't need to be a retrievable resource at the URI; it's merely an
identifier that is easy to deal with and easy to make unique. If it happens to
look like a URL, that does not mean that there will ever be an attempt to go
get something from that URL. So you needn't worry about your intranet.

Example of names in namespaces:

  'title' in the namespace 'http://purl.org/dc/elements/1.1/'
  'title' in the namespace 'urn:something-i-just-made-up'

  You might sometimes see them written like this:

  {http://purl.org/dc/elements/1.1/}title
  {urn:something-i-just-made-up}title

In XML, to put a name in a namespace, you have two options:

1. You can declare a default namespace that applies to the name of the element
where the declaration occurs, and all its descendants, until the namespace is
redeclared or undeclared. The declaration is made with an xmlns attribute,
like this:

  <info>
    <book>
      <title xmlns="http://purl.org/dc/elements/1.1/";>Moby Dick</title>
      <author>Herman Melville</author>
    </book>
    <contact>
      <name>Jane Doe</name>
      <title xmlns="urn:something-i-just-made-up">Editor-In-Chief</title>
    </contact>
  </info>

2. You can bind a prefix to the namespace URI and then use the prefix in the
element or attribute names, like this:

  <info xmlns:dc="http://purl.org/dc/elements/1.1/";
        xmlns:foo="urn:something-i-just-made-up">
    <book>
      <dc:title>Moby Dick</dc:title>
      <author>Herman Melville</author>
    </book>
    <contact>
      <name>Jane Doe</name>
      <foo:title>Editor-In-Chief</foo:title>
    </contact>
  </info>

XML defines a default binding of the prefix 'xml' to the namespace URI
'http://www.w3.org/XML/1998/namespace'.

In the XPath/XSLT data model, namespaces manifest as nodes in the tree. The
example #1 above looks like this:

root
  |___element 'info'
        |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |___text '\n  '
        |___element 'book'
        |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |___text '\n    '
        |     |___element 'title' in ns 'http://purl.org/dc/elements/1.1/' ('title')
        |     |     |  \___namespace '' = 'http://purl.org/dc/elements/1.1/'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Moby Dick'
        |     |___text '\n    '
        |     |___element 'author'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Herman Melville'
        |     |___text '\n  '
        |___text '\n  '
        |___element 'contact'
        |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |___text '\n    '
        |     |___element 'name'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Jane Doe'
        |     |___text '\n    '
        |     |___element 'title' in ns 'urn:something-i-just-made-up' ('title')
        |     |     |  \___namespace '' = 'urn:something-i-just-made-up'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Editor-In-Chief'
        |     |___text '\n  '
        |___text '\n'

Where it says namespace '', that means the default namespace.

The example #2 looks like this:

root
  |___element 'info'
        |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |___text '\n  '
        |___element 'book'
        |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |___text '\n    '
        |     |___element 'title' in ns 'http://purl.org/dc/elements/1.1/' ('dc:title')
        |     |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Moby Dick'
        |     |___text '\n    '
        |     |___element 'author'
        |     |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Herman Melville'
        |     |___text '\n  '
        |___text '\n  '
        |___element 'contact'
        |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |___text '\n    '
        |     |___element 'name'
        |     |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Jane Doe'
        |     |___text '\n    '
        |     |___element 'title' in ns 'urn:something-i-just-made-up' ('foo:title')
        |     |     |  \___namespace 'dc' = 'http://purl.org/dc/elements/1.1/'
        |     |     |  \___namespace 'foo' = 'urn:something-i-just-made-up'
        |     |     |  \___namespace 'xml' = 'http://www.w3.org/XML/1998/namespace'
        |     |     |___text 'Editor-In-Chief'
        |     |___text '\n  '
        |___text '\n'

Note how the namespaces being declared high in the tree resulted in namespace
nodes appearing on all the descendant elements.

In XSLT, at any place where you access an element by name, you can
use a prefixed name instead. Just make sure the prefix is already in
scope before you use it:

  <xsl:template match="book" xmlns:dc="http://purl.org/dc/elements/1.1/";>
    <xsl:text>The book's title is: </xsl:text>
    <xsl:value-of select="dc:title"/>
  </xsl:template>

Attribute names don't inherit namespace URIs from their elements, so if you
want to put an attribute name in a namespace, you have to use a prefix. 
Example:

  <album dc:title="Dark Side Of The Moon"/>

There you go.

   - Mike
____________________________________________________________________________
  mike j. brown                   |  xml/xslt: http://skew.org/xml/
  denver/boulder, colorado, usa   |  resume: http://skew.org/~mike/resume/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread