Working with XML Namespaces in ActionScript

Namespaces are used in XML to help group XML elements and attributes into sets of similar functionality; it is used especially in RSS.
In the XML document, Namespace is defined with an attribute xmlns to which is assigned (with colon : ) a prefix (a name) for Namespace name, and a string for its value, which is usually a URI (Uniform Resource Identifier) address.
The syntax is:

xmlns:namespaceName="URI"
For example:
<pictures xmlns:ns="http://coursesweb.net">
  <ns:image>img1.jpg</ns:image>
  <image>img2.png</image>
</pictures>
- "ns" represents the name of the Namespace, it can be any word.
- "http://coursesweb.net" is the identification value for this Namespace (this can be any string, but usually it's a URI adresses, which can be non-valid URI).

The URI for an XML namespace doesn't have anything to do with a web site located there; it's only to provide a unique string.


Elements and attributes with the same Namespace name are considered as being part of the same group.
Namespaces can be declared in the element which uses it or in the root. You can define multiple namespaces in the same tag.

Working with namespace in AS3

There are multiple XML class methods in ActionScript used for working with namespace:
In E4X, XML namespace attributes are not represented as attributes (they cannot be accessed via attributes() or someElement.@*). They are accessed via namespace() method.
  Example:
// Variable with XML data
var galery:XML = <pictures xmlns:ns="http://coursesweb.net">
  <ns:image>img1.jpg</ns:image>
  <image>img2.png</image>
</pictures>;

trace(galery.image[0].namespace('ns'));      // http://coursesweb.net
trace(galery.image[1].namespace('ns'));      // Error #1010: A term is undefined

• To add a namespace dynamically to an XML object in ActionScript, you must create the namespace in an instance of the Namespace class.
The prefix (namespaceName) and the value of the namespace can be added as arguments when the instance is created:
new Namespace("prefix", "value_uri");
Then use this instance as argument in the "addNamespace()" method.

Or you can create the Namespace instance without arguments, and then add the "prefix" and its value by using the properties of the Namespace class: prefix and uri. These properties can also be used to access and edit later the name and the value stored in the Namespace object.
var name_var:Namespace = new Namespace();
name_var.prefix = "namespaceName";
name_var.uri = "value_uri";

Let's see an example. We define a simple XML format, with two tags in the root, and an attribute in the second tag.
Then we create a namespace and set it to the first element and to the attribute in the second tag.
// Variable with XML data
var test:XML = <root>
    <tag>Text elm1</tag>
    <tag atr="val">Elm 2</tag>
  </root>;

// define the instance with the namespace
var ns1:Namespace = new Namespace('ns', 'coursesweb.net/flash');

// Add the namespace in the XML object (in root)
test.addNamespace(ns1);

test.tag[0].setNamespace(ns1);         // Sets "ns" to the first <tag>

// Sets "ns" at the "atr" attribute in the second <tag>
test.tag[0].@atr.setNamespace(ns1);
// Or:        test.children()[1].@atr.setNamespace(ns1);

trace(test);
- This example displays in Output the following XML format:
<root xmlns:ns="coursesweb.net/flash">
  <ns:tag>Text elm1</ns:tag>
  <tag ns:atr="val">Elm 2</tag>
</root>
- As you can notice, the namespace was added in the XML content, in the root tag, and set to the first <tag> and to "atr".

• tag[index] accesses the tags without a namespace, so the "tag[0]" returns the first element without a namespace, not strictly the first element in the XML object. To avoid confusion that appears in these cases, to use the order in which the elements are in the XML object, you can use the "children()" method.
For example:         test.children()[1].@atr.setNamespace(ns1);

Using the double-colon operator (::)

E4X defines another operator for accessing nodes with namespaces: the double colon (::).
With this operator you can access nodes (elements, attributes) that have the same namespace.
First, use the namespace('prefix') method to add in a Namespace instance the nodes which have the "prefix" namespace, then you can access them with the double-colon (::) operator, using the following syntax:
XMLobject.instanceNamespace::node
To understand it better, see the following example:
// Variable with XML data
var galery:XML = <pictures xmlns:ns="http://coursesweb.net">
    <ns:image>img1.jpg</ns:image>
    <ns:image ns:title="Img 2">img2.png</image>
  </pictures>

// Add in a namespace instance all the elements (and attributes) with "ns" 
var name_s:Namespace = galery.namespace('ns');

trace(galery.name_s::image[0]);                     // img1.jpg
trace(galery.name_s::image[1].@name_s::title);      // Img 2
- Notice in the XML format how the namespace is applied to elements and attributes (ns:tag , ns:attribute).
The instance "name_s" stores the items which have the "ns" namespace (in a numeric order, like an Array), and then these items are accesed with the (::) operator, as presented in the syntax above.

The (::) operator can also be used to edit and delete the elements stored in the Namespace instance.
For example:
galery.name_s::image[1].@name_s::title = 'Another title';
- Modify the value of the "title" attribute in the second <image> element.

And the expression:
delete galery.name_s::image[0];
- Delete the first <image> element.

• Elements with namespace in a XML object can be accessed through hierarchical methods ( child((), children() ), or through a Namespace instance and the double-colon (::) operator.
The expression "element[index]" accesses only the elements without namespace, as seen in the following example.
// Variable with the XML data
var test:XML = <root xmlns:ns="coursesweb.net/flash">
    <ns:tag>Text elm1</ns:tag>
    <tag ns:atr="val">Elm 2</tag>
  </root>

// Returns the value of the first element, using tag[0]
trace(test.tag[0]);          // Elm 2   (it is the second, but the first without namespace)

// Returns the value of the first element, using children()[0]
trace(test.children()[0]);         // Text elm1

To download the FLA file with the examples from this lesson, click: Working with XML Namespaces in AS3.