ACEXML_NamespaceSupport Class Reference

ACEXML_NamespaceSupport provides namespace management operation for an XML parser. More...

#include <ACEXML/common/NamespaceSupport.h>

Collaboration diagram for ACEXML_NamespaceSupport:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACEXML_NamespaceSupport (void)
 ~ACEXML_NamespaceSupport (void)
int init (void)
int declarePrefix (const ACEXML_Char *prefix, const ACEXML_Char *uri)
int getDeclaredPrefixes (ACEXML_STR_LIST &prefixes) const
const ACEXML_ChargetPrefix (const ACEXML_Char *uri) const
int getPrefixes (ACEXML_STR_LIST &prefixes) const
int getPrefixes (const ACEXML_Char *uri, ACEXML_STR_LIST &prefixes) const
const ACEXML_ChargetURI (const ACEXML_Char *prefix) const
int popContext (void)
int processName (const ACEXML_Char *qName, const ACEXML_Char *&uri, const ACEXML_Char *&name, int is_attribute) const
int pushContext (void)
int reset (void)

Static Public Attributes

const ACEXML_CharXMLNS_PREFIX = ACEXML_XMLNS_PREFIX_name
const ACEXML_CharXMLNS = ACEXML_XMLNS_URI_name

Private Attributes

ACEXML_Namespace_Context_Stack ns_stack_
ACEXML_NS_CONTEXTeffective_context_

Detailed Description

ACEXML_NamespaceSupport provides namespace management operation for an XML parser.

This class encapsulates the logic of Namespace processing: it tracks the declarations currently in force for each context and automatically processes qualified XML 1.0 names into their Namespace parts; it can also be used in reverse for generating XML 1.0 from Namespaces.

Namespace support objects are reusable, but the reset method must be invoked between each session.

Here is a simple session (in Java :-p):

String parts[] = new String[3]; NamespaceSupport support = new NamespaceSupport(); support.pushContext(); support.declarePrefix("", "http://www.w3.org/1999/xhtml"); support.declarePrefix("dc", "http://www.purl.org/dc#"); String parts[] = support.processName("p", parts, false); System.out.println("Namespace URI: " + parts[0]); System.out.println("Local name: " + parts[1]); System.out.println("Raw name: " + parts[2]); String parts[] = support.processName("dc:title", parts, false); System.out.println("Namespace URI: " + parts[0]); System.out.println("Local name: " + parts[1]); System.out.println("Raw name: " + parts[2]); support.popContext();

Note that this class is optimized for the use case where most elements do not contain Namespace declarations: if the same prefix/URI mapping is repeated for each context (for example), this class will be somewhat less efficient.

See also:
ACEXML_Exception

Definition at line 126 of file NamespaceSupport.h.


Constructor & Destructor Documentation

ACEXML_NamespaceSupport::ACEXML_NamespaceSupport void   ) 
 

Default constructor.

Definition at line 78 of file NamespaceSupport.cpp.

00079   : ns_stack_ (),
00080     effective_context_ (0)
00081 {}

ACEXML_NamespaceSupport::~ACEXML_NamespaceSupport void   ) 
 

Default destructor.

Definition at line 94 of file NamespaceSupport.cpp.

References popContext().

00095 {
00096   while (this->popContext () == 0)
00097     ;
00098 }


Member Function Documentation

int ACEXML_NamespaceSupport::declarePrefix const ACEXML_Char prefix,
const ACEXML_Char uri
 

Declare a Namespace prefix. Return -1 if the prefix was illegal or an internal error occured. Return 0 if the prefix gets declared successfully, 1 if the prefix replaces an existing prefix definition.

Definition at line 101 of file NamespaceSupport.cpp.

References ACEXML_Char, ACEXML_String, ACEXML_TABOO_NS_PREFIX, effective_context_, ACE_Hash_Map_Manager_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::rebind(), and ACE_OS::strcmp().

Referenced by ACE_TMAIN().

00103 {
00104   if (!prefix || !uri)
00105     return -1;
00106 
00107   // Unless predefined by w3.org(?) NS prefix can never start with
00108   // "xml".
00109   if (ACE_OS::strcmp (ACEXML_TABOO_NS_PREFIX, prefix) == 0)
00110     return -1;
00111 
00112   ACEXML_String ns_prefix (prefix, 0, 0);
00113   ACEXML_String ns_uri (uri, 0, 0);
00114 
00115   return this->effective_context_->rebind (ns_prefix, ns_uri);
00116 }

int ACEXML_NamespaceSupport::getDeclaredPrefixes ACEXML_STR_LIST prefixes  )  const
 

Return all prefixes declared in current context in the user-supplied list prefixes. It is user's reponsibility to ensure the list was empty originally.

Definition at line 119 of file NamespaceSupport.cpp.

References ACEXML_NS_CONTEXT_ENTRY, ACEXML_NS_CONTEXT_ITER, ACEXML_STR_LIST, ACE_Hash_Map_Iterator_Ex< ACEXML_String, ACEXML_String, ACE_Hash< ACEXML_String >, ACE_Equal_To< ACEXML_String >, ACE_Null_Mutex >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::ext_id_, and ACE_Hash_Map_Iterator_Base_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::next().

Referenced by ACE_TMAIN().

00120 {
00121   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00122 
00123   // The prefix for default namespace (empty string) is included in
00124   // the return list.
00125   for (ACEXML_NS_CONTEXT_ITER iter (*this->effective_context_);
00126        iter.next (entry) != 0;
00127        iter.advance ())
00128     prefixes.enqueue_tail (entry->ext_id_.c_str ());
00129 
00130   return 0;
00131 }

const ACEXML_Char * ACEXML_NamespaceSupport::getPrefix const ACEXML_Char uri  )  const
 

Return one of the prefixes mapped to a Namespace URI.

Definition at line 134 of file NamespaceSupport.cpp.

References ACEXML_Char, ACEXML_NS_CONTEXT_ENTRY, ACEXML_NS_CONTEXT_ITER, ACEXML_String, ACE_Hash_Map_Iterator_Ex< ACEXML_String, ACEXML_String, ACE_Hash< ACEXML_String >, ACE_Equal_To< ACEXML_String >, ACE_Null_Mutex >::advance(), ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::ext_id_, ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::int_id_, and ACE_Hash_Map_Iterator_Base_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::next().

Referenced by ACE_TMAIN().

00135 {
00136   if (!uri || *uri == 0)
00137     return 0;
00138 
00139   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00140 
00141   for (ACEXML_NS_CONTEXT_ITER iter (*this->effective_context_);
00142        iter.next (entry) != 0;
00143        iter.advance ())
00144     if (entry->int_id_ == ACEXML_String (uri, 0, 0))
00145       return entry->ext_id_.c_str ();
00146 
00147   return 0;                     // Nothing found.
00148 }

int ACEXML_NamespaceSupport::getPrefixes const ACEXML_Char uri,
ACEXML_STR_LIST prefixes
const
 

Return all prefixes currently declared for a URI in the user-supplied list.

Definition at line 165 of file NamespaceSupport.cpp.

References ACEXML_Char, ACEXML_DEFAULT_NS_PREFIX, ACEXML_NS_CONTEXT_ENTRY, ACEXML_NS_CONTEXT_ITER, ACEXML_STR_LIST, ACEXML_String, ACE_Hash_Map_Iterator_Ex< ACEXML_String, ACEXML_String, ACE_Hash< ACEXML_String >, ACE_Equal_To< ACEXML_String >, ACE_Null_Mutex >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::ext_id_, ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::int_id_, and ACE_Hash_Map_Iterator_Base_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::next().

00167 {
00168   if (!uri)
00169     return -1;
00170 
00171   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00172 
00173   for (ACEXML_NS_CONTEXT_ITER iter (*this->effective_context_);
00174        iter.next (entry) != 0;
00175        iter.advance ())
00176     if (entry->int_id_ == ACEXML_String (uri, 0, 0) &&
00177         entry->ext_id_ != ACEXML_String (ACEXML_DEFAULT_NS_PREFIX, 0, 0))
00178       prefixes.enqueue_tail (entry->ext_id_.c_str ());
00179     else
00180       continue;
00181 
00182   return 0;                     // Nothing found.
00183 }

int ACEXML_NamespaceSupport::getPrefixes ACEXML_STR_LIST prefixes  )  const
 

Return all prefixes currently declared in the user-supplied list. @ Known bug: This function should only return user-defined prefixes.

Definition at line 151 of file NamespaceSupport.cpp.

References ACEXML_NS_CONTEXT_ENTRY, ACEXML_NS_CONTEXT_ITER, ACEXML_STR_LIST, ACE_Hash_Map_Iterator_Ex< ACEXML_String, ACEXML_String, ACE_Hash< ACEXML_String >, ACE_Equal_To< ACEXML_String >, ACE_Null_Mutex >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::ext_id_, and ACE_Hash_Map_Iterator_Base_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::next().

Referenced by ACE_TMAIN().

00152 {
00153   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00154 
00155   // The prefix for default namespace (empty string) is not included
00156   // in the return list.
00157   for (ACEXML_NS_CONTEXT_ITER iter (*this->effective_context_);
00158        iter.next (entry) != 0;
00159        iter.advance ())
00160     prefixes.enqueue_tail (entry->ext_id_.c_str ());
00161   return 0;
00162 }

const ACEXML_Char * ACEXML_NamespaceSupport::getURI const ACEXML_Char prefix  )  const
 

Look up a prefix and get the currently-mapped Namespace URI.

Definition at line 186 of file NamespaceSupport.cpp.

References ACEXML_Char, ACEXML_NS_CONTEXT_ENTRY, ACEXML_String, effective_context_, ACE_Hash_Map_Manager_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::find(), and ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::int_id_.

Referenced by ACE_TMAIN().

00187 {
00188   if (!prefix)
00189     return 0;
00190 
00191   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00192 
00193   if (this->effective_context_->find (ACEXML_String (prefix, 0, 0),
00194                                       entry) == 0)
00195     return entry->int_id_.c_str ();
00196   return 0;
00197 }

int ACEXML_NamespaceSupport::init void   ) 
 

Initialize the namespace support object

Definition at line 84 of file NamespaceSupport.cpp.

References ACE_NEW_RETURN, ACEXML_NS_CONTEXT, ACEXML_String, ACEXML_TABOO_NS_PREFIX, ACEXML_XMLNS_URI_name, ACE_Hash_Map_Manager_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::bind(), and effective_context_.

Referenced by ACE_TMAIN(), and ACEXML_Parser::initialize().

00085 {
00086   // @@ No way to tell if the new fails.
00087   ACE_NEW_RETURN (effective_context_, ACEXML_NS_CONTEXT(), -1);
00088 
00089   ACEXML_String prefix (ACEXML_TABOO_NS_PREFIX, 0, 0);
00090   ACEXML_String uri (ACEXML_XMLNS_URI_name, 0, 0);
00091   return this->effective_context_->bind (prefix, uri);
00092 }

int ACEXML_NamespaceSupport::popContext void   ) 
 

Revert to the previous namespace context.

Definition at line 49 of file NamespaceSupport.cpp.

References effective_context_, ns_stack_, and ACEXML_Namespace_Context_Stack::pop().

Referenced by ACE_TMAIN(), reset(), and ~ACEXML_NamespaceSupport().

00050 {
00051   delete this->effective_context_;
00052 
00053   if ((this->effective_context_ = this->ns_stack_.pop ()) == 0)
00054     return -1;
00055   return 0;
00056 }

int ACEXML_NamespaceSupport::processName const ACEXML_Char qName,
const ACEXML_Char *&  uri,
const ACEXML_Char *&  name,
int  is_attribute
const
 

Process a raw XML 1.0 name. qName is the raw XML name we want to parse, uri contains the URI string of the raw name. It points to a null string if the namespace is not valid or there's no namespace defined. name contains the original name without the prefix. is_attribute specifies whether the name is an attribute or not. Attributes have different scoping rules from elements.

Definition at line 200 of file NamespaceSupport.cpp.

References ACE_TEXT, ACEXML_Char, ACEXML_DEFAULT_NS_PREFIX, ACEXML_NS_CONTEXT_ENTRY, ACEXML_String, effective_context_, ACE_Hash_Map_Manager_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::find(), ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::int_id_, and ACE_OS::strlen().

Referenced by ACE_TMAIN().

00204 {
00205   int qlen = static_cast<int> (ACE_OS::strlen (qName));
00206   int len = -1;
00207   for (int i = 0; i < qlen; ++i)
00208     if (qName [i] == ':')
00209       {
00210         len = i;
00211         break;
00212       }
00213 
00214   ACEXML_String prefix (ACE_TEXT(""),0,0);
00215   if (len == -1)
00216       name = qName;
00217   else
00218     {
00219       prefix.set (qName, len, 1);
00220       name = qName + len + 1;
00221     }
00222 
00223   if (is_attribute && len == -1) {
00224     uri = ACEXML_DEFAULT_NS_PREFIX;
00225     return 0;
00226   }
00227 
00228   ACEXML_NS_CONTEXT_ENTRY *entry;
00229 
00230   if (this->effective_context_->find (prefix, entry) == 0)
00231     uri = entry->int_id_.c_str ();
00232   else
00233     {
00234       uri = ACEXML_DEFAULT_NS_PREFIX;
00235       return -1;
00236     }
00237   return 0;
00238 }

int ACEXML_NamespaceSupport::pushContext void   ) 
 

Start a new Namespace context. Prefixes defined in previous context are copied over to the new context.

Definition at line 59 of file NamespaceSupport.cpp.

References ACE_NEW_RETURN, ACEXML_NS_CONTEXT, ACEXML_NS_CONTEXT_ENTRY, ACEXML_NS_CONTEXT_ITER, ACE_Hash_Map_Iterator_Ex< ACEXML_String, ACEXML_String, ACE_Hash< ACEXML_String >, ACE_Equal_To< ACEXML_String >, ACE_Null_Mutex >::advance(), ACE_Hash_Map_Manager_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::bind(), effective_context_, ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::ext_id_, ACE_Hash_Map_Entry< ACEXML_String, ACEXML_String >::int_id_, ACE_Hash_Map_Iterator_Base_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::next(), ns_stack_, and ACEXML_Namespace_Context_Stack::push().

Referenced by ACE_TMAIN().

00060 {
00061   ACEXML_NS_CONTEXT *temp = this->effective_context_;
00062   ACE_NEW_RETURN (this->effective_context_,
00063                   ACEXML_NS_CONTEXT (),
00064                   -1);
00065 
00066   // @@ Copy everything from the old context to the new one.
00067   ACEXML_NS_CONTEXT_ENTRY *entry = 0;
00068 
00069   for (ACEXML_NS_CONTEXT_ITER iter (*temp);
00070        iter.next (entry) != 0;
00071        iter.advance ())
00072     this->effective_context_->bind (entry->ext_id_,
00073                                     entry->int_id_);
00074   this->ns_stack_.push (temp);
00075   return 0;
00076 }

int ACEXML_NamespaceSupport::reset void   ) 
 

Reset this Namespace support object for reuse.

Definition at line 241 of file NamespaceSupport.cpp.

References popContext().

00242 {
00243   while (this->popContext() != -1)
00244     ;
00245   return 0;
00246 }


Member Data Documentation

ACEXML_NS_CONTEXT* ACEXML_NamespaceSupport::effective_context_ [private]
 

The effective namespace context.

Definition at line 230 of file NamespaceSupport.h.

Referenced by declarePrefix(), getURI(), init(), popContext(), processName(), and pushContext().

ACEXML_Namespace_Context_Stack ACEXML_NamespaceSupport::ns_stack_ [private]
 

Namespace Context stack. When we entering a new namespace context, the old context is duplicated and pushed into this stack.

Definition at line 225 of file NamespaceSupport.h.

Referenced by popContext(), and pushContext().

const ACEXML_Char * ACEXML_NamespaceSupport::XMLNS = ACEXML_XMLNS_URI_name [static]
 

Definition at line 15 of file NamespaceSupport.cpp.

const ACEXML_Char * ACEXML_NamespaceSupport::XMLNS_PREFIX = ACEXML_XMLNS_PREFIX_name [static]
 

XMLNS default prefix and URI strings.

Definition at line 8 of file NamespaceSupport.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:48:02 2006 for ACEXML by doxygen 1.3.6