📄 parser.cpp
字号:
ACEXML_Char ch = this->skip_whitespace (0);
while (state < 2)
{
switch (ch)
{
case '?':
if (state == 0)
state = 1;
break;
case '>':
if (state == 1)
{
instruction = this->obstack_.freeze ();
this->content_handler_->processingInstruction (pitarget,
instruction ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK_RETURN (-1);
this->obstack_.unwind (ACE_const_cast (ACEXML_Char*, pitarget));
return 0;
}
break;
case 0x0D: // End-of-Line handling
ch = (this->peek () == 0x0A ? this->get () : 0x0A);
// Fall thru...
case 0x0A:
// Fall thru...
default:
if (state == 1)
this->obstack_.grow ('?');
this->obstack_.grow (ch);
state = 0;
}
ch = this->get ();
}
return -1;
}
int
ACEXML_Parser::parse_doctypedecl (ACEXML_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((ACEXML_SAXException))
{
if (this->parse_token (ACE_TEXT ("DOCTYPE")) < 0)
{
this->report_fatal_error(ACE_TEXT ("Expecting keyword 'DOCTYPE'") ACEXML_ENV_ARG_PARAMETER);
return -1;
}
ACEXML_Char nextch = this->skip_whitespace (0);
if (nextch == 0)
{
this->report_fatal_error(ACE_TEXT ("Expecting a DOCTYPE name") ACEXML_ENV_ARG_PARAMETER);
return -1;
}
this->doctype_ = this->read_name (nextch);
this->skip_whitespace_count (&nextch);
if (nextch == 'S' || nextch == 'P') // ExternalID defined
{
this->parse_external_id_and_ref (this->dtd_public_,
this->dtd_system_
ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK_RETURN (-1);
// if (this->dtd_public_ == 0)
// ACE_DEBUG ((LM_DEBUG,
// ACE_TEXT ("ACEXML Parser got external DTD id: SYSTEM %s\n"),
// this->dtd_system_));
// else
// ACE_DEBUG ((LM_DEBUG,
// ACE_TEXT ("ACEXML Parser got DTD external id: PUBLIC %s %s\n"),
// this->dtd_public_, this->dtd_system_));
}
nextch = this->skip_whitespace (0);
switch (nextch)
{
case '[': // Internal DTD definition
if (this->parse_internal_dtd (ACEXML_ENV_SINGLE_ARG_PARAMETER) < 0)
return -1; // Error in markupdecl
break;
case '>': // End of DTD definition
// this is an XML document without a dectypedecl.
return 0;
case '0':
this->report_fatal_error (ACE_TEXT ("Unexpected EOF") ACEXML_ENV_ARG_PARAMETER);
return -1;
default:
break;
}
if (this->skip_whitespace (0) != '>')
{
this->report_fatal_error(ACE_TEXT ("Internal error") ACEXML_ENV_ARG_PARAMETER);
return -1;
}
return 0;
}
void
ACEXML_Parser::parse_element (int is_root ACEXML_ENV_ARG_DECL)
ACE_THROW_SPEC ((ACEXML_SAXException))
{
// Parse STag.
const ACEXML_Char *startname = this->read_name ();
if (startname == 0)
{
this->report_fatal_error (ACE_TEXT ("Unexpected EOF") ACEXML_ENV_ARG_PARAMETER);
return;
}
if (is_root && this->doctype_ != 0
&& ACE_OS::strcmp (startname, this->doctype_) != 0)
{
this->report_fatal_error (ACE_TEXT ("Root element missing") ACEXML_ENV_ARG_PARAMETER);
return;
}
ACEXML_AttributesImpl attributes;
ACEXML_Char ch;
int new_namespace = 0;
const ACEXML_Char *endname = 0;
const ACEXML_Char *ns_uri, *ns_lname; // namespace URI and localName
ACEXML_Char* prefix = 0;
ACEXML_Char* name = 0;
for (int start_element_done = 0; start_element_done == 0;)
{
ch = this->skip_whitespace (0);
switch (ch)
{
case 0:
this->report_fatal_error(ACE_TEXT ("Internal error") ACEXML_ENV_ARG_PARAMETER);
return;
case '/':
if (this->get () != '>')
{
this->report_fatal_error(ACE_TEXT ("Expecting '>'") ACEXML_ENV_ARG_PARAMETER);
return;
}
else
{
this->xml_namespace_.processName(startname, ns_uri, ns_lname, 0);
prefix = ACE_const_cast (ACEXML_Char*,
this->xml_namespace_.getPrefix(ns_uri));
this->report_prefix_mapping (prefix, ns_uri, ns_lname, 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->report_prefix_mapping (prefix, ns_uri, ns_lname, 0 ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK;
}
if (new_namespace != 0)
this->xml_namespace_.popContext ();
return;
case '>':
{
this->xml_namespace_.processName (startname, ns_uri, ns_lname, 0);
prefix = ACE_const_cast (ACEXML_Char*,
this->xml_namespace_.getPrefix (ns_uri));
this->report_prefix_mapping (prefix, ns_uri, ns_lname, 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->read_name (ch);
if (attname == 0 ||
this->skip_equal () != 0 ||
this->get_quoted_string (attvalue) != 0)
{
this->report_fatal_error(ACE_TEXT ("Error reading attribute") 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 (new_namespace == 0)
{
this->xml_namespace_.pushContext ();
new_namespace = 1;
}
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->report_fatal_error(ACE_TEXT ("Duplicate namespace 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 (0, 0, attname,
default_attribute_type,
attvalue) == -1)
{
this->report_fatal_error(ACE_TEXT ("Duplicate attribute found") ACEXML_ENV_ARG_PARAMETER);
return;
}
}
if (!this->namespaces_ && !this->namespace_prefixes_)
{
this->report_fatal_error(ACE_TEXT ("Both namespaces feature and namespace_prefixes feature are false. Illegal Mode") 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->report_fatal_error(ACE_TEXT ("Duplicate attribute found") ACEXML_ENV_ARG_PARAMETER);
return;
}
}
break;
}
}
ACEXML_Char *cdata;
size_t cdata_length = 0;
// Parse element contents.
while (1)
{
ACEXML_Char ch = this->get ();
switch (ch)
{
case 0:
this->report_fatal_error(ACE_TEXT ("Internal error") ACEXML_ENV_ARG_PARAMETER);
return;
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;
this->obstack_.unwind (cdata);
cdata_length = 0;
}
switch (this->peek ())
{
case '!': // a comment or a CDATA section.
this->get (); // consume '!'
ch = this->peek ();
if (ch == '-') // a comment
{
if (this->grok_comment () < 0)
{
this->report_fatal_error(ACE_TEXT ("Error parsing comment") ACEXML_ENV_ARG_PARAMETER);
return;
}
}
else if (ch == '[') // a CDATA section.
{
this->parse_cdata (ACEXML_ENV_SINGLE_ARG_PARAMETER);
ACEXML_CHECK;
}
else
{
this->report_fatal_error(ACE_TEXT ("Unexpected character") ACEXML_ENV_ARG_PARAMETER);
return;
}
break;
case '?': // a PI.
this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
ACEXML_CHECK;
break;
case '/': // an ETag.
{
this->get (); // consume '/'
endname = this->read_name ();
if (endname == 0 ||
ACE_OS::strcmp (startname, endname) != 0)
{
this->report_fatal_error(ACE_TEXT ("Mismatched End-tag encountered") ACEXML_ENV_ARG_PARAMETER);
return ;
}
if (this->skip_whitespace (0) != '>')
{
this->report_fatal_error(ACE_TEXT ("Expecting '>' in an end-tag") ACEXML_ENV_ARG_PARAMETER);
return;
}
this->content_handler_->endElement (ns_uri, ns_lname, endname ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK;
prefix = ACE_const_cast (ACEXML_Char*,
this->xml_namespace_.getPrefix(ns_uri));
this->report_prefix_mapping (prefix, ns_uri, ns_lname, 0 ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK;
if (new_namespace != 0)
this->xml_namespace_.popContext ();
return;
}
default: // a new nested element?
this->parse_element (0 ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK;
break;
}
break;
case '&':
{
const ACEXML_String *replace = 0;
ACEXML_String charval;
ACEXML_Char buffer[6];
if (this->peek () == '#')
{
if (this->parse_char_reference (buffer, 6) != 0)
{
// not referring to any character exception?
return;
}
charval.set (buffer, 0);
replace = &charval;
}
else
replace = this->parse_reference ();
if (replace == 0)
{
this->report_fatal_error(ACE_TEXT ("Internal error") ACEXML_ENV_ARG_PARAMETER);
return;
}
// if (this->try_grow_cdata (replace->length (),
// cdata_length, xmlenv) == 0)
// {
cdata_length = replace->length ();
for (size_t i = 0; i < replace->length (); ++i)
this->obstack_.grow ((*replace)[i]);
// }
// else
// return;
}
break;
case 0x0D: // End-of-Line handling
ch = (this->peek () == 0x0A ? this->get () : 0x0A);
// Fall thru...
case 0x0A:
// Fall thru...
default:
++cdata_length;
cdata = this->obstack_.grow (ch);
if (cdata == 0)
{
cdata = this->obstack_.freeze ();
this->content_handler_->characters (cdata,
0,
cdata_length ACEXML_ENV_ARG_PARAMETER);
ACEXML_CHECK;
this->obstack_.grow (ch);
cdata_length = 1; // the missing char.
}
}
}
ACE_NOTREACHED (return;)
}
int
ACEXML_Parser::parse_char_reference (ACEXML_Char *buf, size_t len)
{
if (this->get () != '#')
{
// Internal error.
return -1;
}
int hex = 0;
if (this->peek () == 'x')
{
hex = 1;
this->get ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -