#include <ACEXML/common/NamespaceSupport.h>
Collaboration diagram for ACEXML_NamespaceSupport:
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_Char * | getPrefix (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_Char * | getURI (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 | |
static const ACEXML_Char * | XMLNS_PREFIX = ACEXML_XMLNS_PREFIX_name |
static const ACEXML_Char * | XMLNS = ACEXML_XMLNS_URI_name |
Private Attributes | |
ACEXML_Namespace_Context_Stack | ns_stack_ |
ACEXML_NS_CONTEXT * | effective_context_ |
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.
Definition at line 126 of file NamespaceSupport.h.
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 | ) |
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_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, false); 00113 ACEXML_String ns_uri (uri, 0, false); 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 ACE_Hash_Map_Iterator_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), 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 ACE_Hash_Map_Iterator_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::advance(), 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, false)) 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_DEFAULT_NS_PREFIX, ACE_Hash_Map_Iterator_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), 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, false) && 00177 entry->ext_id_ != ACEXML_String (ACEXML_DEFAULT_NS_PREFIX, 0, false)) 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 ACE_Hash_Map_Iterator_Ex< EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK >::advance(), ACE_Unbounded_Queue< T >::enqueue_tail(), 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 ACE_Hash_Map_Entry< EXT_ID, INT_ID >::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, false), 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_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().
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, false); 00090 ACEXML_String uri (ACEXML_XMLNS_URI_name, 0, false); 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_.
Referenced by ACE_TMAIN(), ACEXML_Parser::parse_content(), and ACEXML_Parser::parse_element().
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_DEFAULT_NS_PREFIX, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, ACE_String_Base< CHAR >::set(), and ACE_OS::strlen().
Referenced by ACE_TMAIN(), and ACEXML_Parser::parse_element().
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, false); 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, effective_context_, ns_stack_, and ACEXML_Namespace_Context_Stack::push().
Referenced by ACE_TMAIN(), and ACEXML_Parser::parse_element().
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.
Referenced by ACEXML_Parser::reset().
The effective namespace context.
Definition at line 230 of file NamespaceSupport.h.
Referenced by declarePrefix(), init(), popContext(), and pushContext().
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 pushContext().
const ACEXML_Char * ACEXML_NamespaceSupport::XMLNS = ACEXML_XMLNS_URI_name [static] |
Definition at line 148 of file NamespaceSupport.h.
const ACEXML_Char * ACEXML_NamespaceSupport::XMLNS_PREFIX = ACEXML_XMLNS_PREFIX_name [static] |
XMLNS default prefix and URI strings.
Definition at line 147 of file NamespaceSupport.h.