📄 parser.cpp
字号:
this->fatal_error(ACE_TEXT ("Invalid systemLiteral") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } break; case 'P': // External PUBLIC id or previously defined PUBLIC id. if (this->parse_token (ACE_TEXT ("UBLIC")) < 0 || this->skip_whitespace_count () < 1) { this->fatal_error(ACE_TEXT ("Expecing keyword PUBLIC") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } if (this->parse_pubid_literal (publicId) != 0) { this->fatal_error(ACE_TEXT ("Invalid PubidLiteral") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } this->skip_whitespace_count(&fwd); if (fwd == '\'' || fwd == '"') { if (this->parse_system_literal (systemId) != 0) { this->fatal_error(ACE_TEXT ("Invalid systemLiteral") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } } else if (this->ref_state_ != ACEXML_ParserInt::IN_NOTATION) { this->fatal_error(ACE_TEXT ("Expecting systemLiteral after a ") ACE_TEXT ("PUBLIC keyword") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } break; default: this->fatal_error(ACE_TEXT ("Invalid system/public Literal") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } return 0;}ACEXML_Char*ACEXML_Parser::normalize_systemid (const ACEXML_Char* systemId){ if (ACE_OS::strstr (systemId, ACE_TEXT("ftp://")) != 0 || ACE_OS::strstr (systemId, ACE_TEXT ("http://")) != 0 || ACE_OS::strstr (systemId, ACE_TEXT ("file://")) != 0) return 0; else { ACEXML_Char* normalized_uri = 0; const ACEXML_Char* baseURI = this->current_->getLocator()->getSystemId(); ACE_ASSERT (baseURI); const ACEXML_Char* temp = 0; if (ACE_OS::strstr (baseURI, ACE_TEXT ("http://")) != 0) // baseURI is a HTTP URL and systemId is relative. Note that this // is not compliant with RFC2396. Caveat Emptor ! temp = ACE_OS::strrchr (baseURI, '/'); else // baseURI is a local file and systemId is relative // Unlike the HTTP one, this will work always. temp = ACE_OS::strrchr (baseURI,ACE_DIRECTORY_SEPARATOR_CHAR); if (temp) { size_t pos = temp - baseURI + 1; size_t len = pos + ACE_OS::strlen (systemId) + 1; ACE_NEW_RETURN (normalized_uri, ACEXML_Char[len], 0); ACE_OS::strncpy (normalized_uri, baseURI, pos); ACE_OS::strcpy (normalized_uri + pos, systemId); return normalized_uri; } return 0; }}voidACEXML_Parser::parse_element (int is_root ACEXML_ENV_ARG_DECL) ACE_THROW_SPEC ((ACEXML_SAXException)){ // Parse STag. const ACEXML_Char *startname = this->parse_name (); if (startname == 0) { this->fatal_error (ACE_TEXT ("Unexpected end-of-file") ACEXML_ENV_ARG_PARAMETER); return; } if (is_root && this->doctype_ != 0 && ACE_OS::strcmp (startname, this->doctype_) != 0) { this->fatal_error (ACE_TEXT ("Root element different from DOCTYPE") ACEXML_ENV_ARG_PARAMETER); return ; } ACEXML_AttributesImpl attributes; ACEXML_Char ch; int ns_flag = 0; // Push only one namespace context onto the stack // if there are multiple namespaces declared. const ACEXML_Char* ns_uri = 0; const ACEXML_Char* ns_lname = 0; // namespace URI and localName for (int start_element_done = 0; start_element_done == 0;) { ch = this->skip_whitespace (); switch (ch) { case 0: this->fatal_error(ACE_TEXT ("Internal Parser error") ACEXML_ENV_ARG_PARAMETER); return; case '/': if (this->get () != '>') { this->fatal_error(ACE_TEXT ("Expecting '>' at end of element ") ACE_TEXT ("definition") ACEXML_ENV_ARG_PARAMETER); return; } this->xml_namespace_.processName(startname, ns_uri, ns_lname, 0); this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri), ns_uri, 1 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; this->content_handler_->startElement(ns_uri, ns_lname, startname, &attributes ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; this->content_handler_->endElement (ns_uri, ns_lname, startname ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri), ns_uri, 0 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; if (ns_flag) { this->xml_namespace_.popContext (); this->nested_namespace_--; } return; case '>': this->xml_namespace_.processName (startname, ns_uri, ns_lname, 0); this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri), ns_uri, 1 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; this->content_handler_->startElement(ns_uri, ns_lname, startname, &attributes ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK; start_element_done = 1; break; default: ACEXML_Char *attvalue = 0; ACEXML_Char *attname = this->parse_name (ch); if (attname == 0 || this->skip_equal () != 0 || this->parse_attvalue (attvalue ACEXML_ENV_ARG_PARAMETER) != 0) { this->fatal_error(ACE_TEXT ("Error reading attribute value") ACEXML_ENV_ARG_PARAMETER); return; } // Handling new namespace if any. Notice that the order of // namespace declaration does matter. if (ACE_OS::strncmp (attname, ACE_TEXT("xmlns"), 5) == 0) { if (this->namespaces_) { if (!ns_flag) { this->xml_namespace_.pushContext (); this->nested_namespace_++; ns_flag = 1; } ACEXML_Char* name = ACE_OS::strchr (attname, ':'); const ACEXML_Char* ns_name = (name == 0)? empty_string:name+1; if (this->xml_namespace_.declarePrefix (ns_name, attvalue) == -1) { this->fatal_error(ACE_TEXT ("Duplicate definition of ") ACE_TEXT ("prefix") ACEXML_ENV_ARG_PARAMETER); return; } } if (this->namespace_prefixes_) { // Namespace_prefixes_feature_ is required. So add the // xmlns:foo to the list of attributes. if (attributes.addAttribute (ACE_TEXT (""), ACE_TEXT (""), attname, default_attribute_type, attvalue) == -1) { this->fatal_error(ACE_TEXT ("Duplicate attribute ") ACE_TEXT ("definition. Hint: Try ") ACE_TEXT ("setting namespace_prefix") ACE_TEXT ("es feature to 0") ACEXML_ENV_ARG_PARAMETER); return; } } if (!this->namespaces_ && !this->namespace_prefixes_) { this->fatal_error(ACE_TEXT ("One of namespaces or ") ACE_TEXT ("namespace_prefixes should be") ACE_TEXT (" declared") ACEXML_ENV_ARG_PARAMETER); return; } } else { const ACEXML_Char *uri, *lName; this->xml_namespace_.processName (attname, uri, lName, 1); if (attributes.addAttribute (uri, lName, attname, default_attribute_type, attvalue) == -1) { this->fatal_error(ACE_TEXT ("Duplicate attribute ") ACE_TEXT ("definition") ACEXML_ENV_ARG_PARAMETER); return; } } break; } } if (this->parse_content (startname, ns_uri, ns_lname, ns_flag ACEXML_ENV_ARG_PARAMETER) != 0) return;}intACEXML_Parser::parse_content (const ACEXML_Char* startname, const ACEXML_Char*& ns_uri, const ACEXML_Char*& ns_lname, int ns_flag ACEXML_ENV_ARG_DECL) ACE_THROW_SPEC ((ACEXML_SAXException)){ ACEXML_Char *cdata; size_t cdata_length = 0; // Parse element contents. while (1) { ACEXML_Char ch = this->get (); switch (ch) { case 0: this->pop_context (1 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); break; case '<': // Push out old 'characters' event. if (cdata_length != 0) { cdata = this->obstack_.freeze (); this->content_handler_->characters (cdata, 0, cdata_length ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); this->obstack_.unwind (cdata); cdata_length = 0; } ch = this->peek(); switch (ch) { case '!': // a comment or a CDATA section. this->get (); // consume '!' ch = this->peek (); if (ch == '-') // a comment { if (this->parse_comment () < 0) { this->fatal_error(ACE_TEXT ("Invalid comment in ") ACE_TEXT ("document") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } } else if (ch == '[') // a CDATA section. { this->parse_cdata (ACEXML_ENV_SINGLE_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } else { this->fatal_error(ACE_TEXT ("Expecting a CDATA section ") ACE_TEXT ("or a comment section") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } break; case '?': // a PI. this->get(); // consume the '?' this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); break; case '/': // an ETag. { this->get (); // consume '/' ACEXML_Char* endname = this->parse_name (); if (endname == 0 || ACE_OS::strcmp (startname, endname) != 0) { this->fatal_error(ACE_TEXT ("Name in ETag doesn't ") ACE_TEXT ("match name in STag") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } if (this->skip_whitespace () != '>') { this->fatal_error(ACE_TEXT ("Expecting '>' at end ") ACE_TEXT ("of element") ACEXML_ENV_ARG_PARAMETER); return -1; } this->content_handler_->endElement (ns_uri, ns_lname, endname ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri), ns_uri, 0 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); if (this->namespaces_ && ns_flag) { if (this->nested_namespace_ >= 1) { this->xml_namespace_.popContext (); this->nested_namespace_--; } } return 0; } default: // a new nested element? this->parse_element (0 ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); break; } break; case '&': if (this->peek () == '#') { ACEXML_Char buf[7]; size_t len = 0; do { len = sizeof (buf); if (this->parse_char_reference (buf, len) != 0) { // [WFC: Legal Character] this->fatal_error (ACE_TEXT ("Invalid CharRef") ACEXML_ENV_ARG_PARAMETER); ACEXML_CHECK_RETURN (-1); } } while (buf[0] == '&' && this->peek() == '#'); for (size_t j = 0; j < len; ++j) this->obstack_.grow (buf[j]); cdata_length += len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -