Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML namespaces and attributes

I'm trying to understand how namespaces work in XML. When I have an element like foo:bar, the attributes will often not have namespaces on them. But sometimes they will. Are the attribute in the namespace of the element, even when the default namespace has been declared? Looking over the xsd for xhtml it seems the attributes are part of the schema and should be in the namespace for xhtml, but they are never presented that way...

like image 941
user4315 Avatar asked Sep 03 '08 12:09

user4315


People also ask

What is namespace attribute?

A Namespace is a set of unique names. Namespace is a mechanisms by which element and attribute name can be assigned to a group. The Namespace is identified by URI(Uniform Resource Identifiers).

Which XML attribute is used to define namespace?

XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax.

Can a namespace have attributes?

When your elements have a namespace and those elements have attributes, then there can be no confusion: the attributes belong to your element, which belongs to your namespace. Adding a namespace prefix to the attributes would just make everything more verbose.

What are attributes in XML?

Attributes are part of XML elements. An element can have multiple unique attributes. Attribute gives more information about XML elements. To be more precise, they define properties of elements.


4 Answers

Most of the time, attributes will not be in any namespace. The namespace spec says (emphasis mine):

A default namespace declaration applies to all unprefixed element names within its scope. Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.

There's a reason that most XML vocabularies use non-namespaced attributes:
When your elements have a namespace and those elements have attributes, then there can be no confusion: the attributes belong to your element, which belongs to your namespace. Adding a namespace prefix to the attributes would just make everything more verbose.

So why do namespaced attributes exist?
Because some vocabularies do useful work with mostly attributes, and can do this when mixed in with other vocabularies. The best known example is XLink.

Lastly, W3C XML Schema has an all too easy way (<schema attributeFormDefault="qualified">) of declaring your attributes as being in a namespace, forcing you to prefix them in your documents, even when you use a default namespace.

like image 140
Bart Schuller Avatar answered Oct 22 '22 17:10

Bart Schuller


Examples to illustrate using the Clark notation, where the namespace prefix is replaced with the namespace URL in curly brackets:

<bar xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>
<bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>
<foo:bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>

is

<{}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>
<{http://www.foo.com/}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>
<{http://www.foo.com/}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>
like image 31
jelovirt Avatar answered Oct 22 '22 18:10

jelovirt


There's something related to this attributes/namespaces subject that took me some time to understand today when I was working on a XSD. I'm going to share this experience with you in case anyone ever happens to have the same issues.

In the Schema Document I was working on there were a couple of global attributes referenced by some elements. To simplify things here let's assume this XSD I'm talking about was about a Customer.

Let's call one of these global attributes Id. And the root element using it Customer

My XSD declaration looked like this :

<?xml version="1.0" encoding="utf-8"?>
<xs:schema  xmlns="http://schemas.mycompany.com/Customer/V1" 
targetNamespace="http://schemas.mycompany.com/Customer/V1" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">

My Id attribute declaration looked like this :

<xs:attribute name="Id" type="xs:positiveInteger"/>

And my Customer element used the attribute like this :

<xs:element name="Customer">
   <xs:complexType>
      <xs:attribute ref="Id" use="required"/>
      <!-- some elements here -->
    </xs:complexType>
</xs:element>

Now, let's say I wanted to declare a Customer XML document like this :

<?xml version="1.0" encoding="utf-8"?>
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1">
  <!-- ... other elements here -->
</Customer>

I found out that I can't : when the attribute is globally declared, it's not in the same namespace than the element who references it.

I figured out that the only solution with the XSD defined like that was to declare the namespace twice: once without a prefix in order to make it the default namespace for elements, and once with a prefix in order to use it with the attributes. So this is how it would have looked like :

<?xml version="1.0" encoding="utf-8"?>
<Customer cus:Id="1" xmlns="http://schemas.mycompany.com/Customer/V1"
 xmlns:cus="http://schemas.mycompany.com/Customer/V1">
  <!-- ... other elements here -->
</Customer>

This is so unpractical that I just decided to get rid of all global attributes and declare them them locally. Wich in the case of the example I gave here would have looked like this:

<xs:element name="Customer">
   <xs:complexType>
       <xs:attribute name="Id" type="xs:positiveInteger" use="required"/>
       <!-- some elements here -->
   </xs:complexType>
</xs:element>

I found it hard to find some references about what I'm talking about here in the net. I eventually found this post in the Stylus XSD Forum where a guy named Steen Lehmann suggested either to declare the attribute locally or to declare it within an attribute group

"so that the attribute declaration itself is no longer global"

This last solution has a "hacky" taste, so I just decided to stick with the first solution and declare all my attributes locally.

like image 43
Diego Tercero Avatar answered Oct 22 '22 18:10

Diego Tercero


Read up at 6.1 Namespace Scoping and 6.2 Namespace Defaulting on w3c.

Basically:

The scope of a namespace declaration declaring a prefix extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag

However, the text here doesn't seem to explain if means a is foo:a or the default namespace in the context. I would assume that it does not refer to foo:a, but rather the documents default namespace a. Considering this quote at least:

Such a namespace declaration applies to all element and attribute names within its scope whose prefix matches that specified in the declaration.

Ie. the namespace "foo:" only applies to elements prefixed with foo:

like image 20
Staale Avatar answered Oct 22 '22 17:10

Staale