Copyright © 1995-2005 Opera Software AS. All rights reserved.
This file is part of the Opera web browser. It may not be distributed
under any circumstances.
$Id$
The XML Utils module provides code for handling XML namespace declarations through the class XMLNamespaceDeclaration. This includes handling XML namespace declaration attributes, maintaining a list of namespace declarations in scope and "resolving" complete names by setting the URI component based on the value of the prefix component and a list of namespace declarations in scope.
The list of namespace declarations in scope is represented as a linked list of XMLNamespaceDeclaration objects via a pointer to the object representing the most recent (nearest) namespace declaration. A null pointer represents an empty list. The objects are reference counted. Each object owns a reference to the previous namespace declaration and external users typically owns a single reference to the head of the list.
The list is maintained while parsing/processing an XML document by pushing and popping objects as namespaces are declared and go out of scope. By adding an extra reference to the current head of the list at any point, users can essentially keep a copy of the list of namespace declarations in scope at that point indefinitely while parsing/processing continues and the list changes.
The list of namespace declarations in scope is updated from new
namespace declaration attributes by calling the static function
XMLNamespaceDeclaration::ProcessAttribute.
It is perfectly legal to call the function to process attributes
that are not namespace declaration attributes. If called to process
such attributes, it will do nothing at all.
The scope of namespace declarations is determined by the
level
argument to
XMLNamespaceDeclaration::ProcessAttribute.
The level of an attribute is typically the number of ancestors the
element on which the attribute was specified. Users are however
free to use other methods to determine the level of an attribute and
thus implement different scoping rules, if appropriate.
In addition from being pushed when processing namespace declaration
attributes, namespace declarations can be pushed manually using one
of the static functions
XMLNamespaceDeclaration::Push
or
XMLNamespaceDeclaration::PushL.
These functions work much the same way as
XMLNamespaceDeclaration::ProcessAttribute
except instead of an attribute name and value, a namespace URI and
prefix is supplied together with the pointer to the head of the
namespace declaration list to update and the level of the namespace
declaration.
The first argument to each of the functions used to push namespace declarations is a pointer to the currently most recent namespace declaration object. This pointer is updated by the functions if a new namespace declaration is pushed to point to the new namespace declaration. One reference to the previous namespace declaration object, which the caller is assumed to own, is transferred to the new namespace declaration object. If the pointer was initially null the caller did not own a reference to any namespace declaration object, but will own one after the function call.
The end of the scope of namespace declarations is signalled by
calling the static function
XMLNamespaceDeclaration::Pop
with the same
level
argument as was used to process the namespace declaration argument
or to push the declaration. Normally, the scope of namespace
declarations end when the element on which the corresponding
namespace declaration attribute was specified ends, so typically
XMLNamespaceDeclaration::Pop
should be called at the end of each element, with the same
level
argument as was used to process that element's attributes. It is
okay to call
XMLNamespaceDeclaration::Pop
at the end of any element, even though no namespace declaration's
scope ends there.
XMLNamespaceDeclaration::Pop
will simply pop any namespace declaration that was pushed with a
equal or higher
level
argument than that used in the call to
XMLNamespaceDeclaration::Pop.
Like to the functions used to push namespace declarations, the first
argument to the function
XMLNamespaceDeclaration::Pop
is a pointer to the object representing the currently most recent
namespace declaration. This pointer is updated if any namespace
declarations are popped, and one reference to the object, which the
caller is assumed to own, is transferred to the object the pointer
points to after the function call. If the last namespace
declaration is popped, the pointer is set to null and the reference
is simply released.
Note: if the list of namespaces in scope is only modified by calls to the pushing and popping functions described here, no explicit reference counting will be necessary, unless processing is stopped before all levels are popped (that is, when the list of namespaces in scope is potentially non-empty.) If processing is so stopped, only a single reference needs to be released.