Handling Errors
During the initial stages of application development, it's possible to get by without using error handlers in your code; however, as an application is being packaged for release, graceful error handling and recovery becomes a must. PHP allows developers to accomplish this error handling via its xml_get_error_code() function (which prints the error code returned by the parser when it hits a bump) and its xml_error_string() function, (which returns a short, human-readable error message corresponding to the error code). Table 2.2 is a list of error codes and their corresponding named constants, together with what they mean.
Table 2.2. SAX Parser Error Codes
|
1
|
XML_ERROR_NO_MEMORY
|
Parser out of memory
|
2
|
XML_ERROR_SYNTAX
|
Syntax error
|
3
|
XML_ERROR_NO_ELEMENTS
|
No element found
|
4
|
XML_ERROR_INVALID_TOKEN
|
Document not well-formed
|
5
|
XML_ERROR_UNCLOSED_TOKEN
|
Unclosed token
|
6
|
XML_ERROR_PARTIAL_CHAR
|
Unclosed token
|
7
|
XML_ERROR_TAG_MISMATCH
|
Mismatched tag
|
8
|
XML_ERROR_DUPLICATE_ATTRIBUTE
|
Duplicate attribute
|
9
|
XML_ERROR_JUNK_AFTER_DOC_ELEMENT
|
Junk after document element
|
10
|
XML_ERROR_PARAM_ENTITY_REF
|
Illegal parameter entity reference found
|
11
|
XML_ERROR_UNDEFINED_ENTITY
|
Undefined entity
|
12
|
XML_ERROR_RECURSIVE_ENTITY_REF
|
Recursive entity reference
|
13
|
XML_ERROR_ASYNC_ENTITY
|
Asynchronous entity
|
14
|
XML_ERROR_BAD_CHAR_REF
|
Reference to invalid character number found
|
15
|
XML_ERROR_BINARY_ENTITY_REF
|
Reference to binary entity found
|
16
|
XML_ERROR_ATTRIBUTE_EXTERNAL_ ENTITY_REF
|
Reference to external entity found within attribute
|
17
|
XML_ERROR_MISPLACED_XML_PI
|
XML processing instruction not found at start of external entity
|
18
|
XML_ERROR_UNKNOWN_ENCODING
|
Unknown document encoding
|
19
|
XML_ERROR_INCORRECT_ENCODING
|
Incorrect document encoding specified
|
20
|
XML_ERROR_UNCLOSED_CDATA_SECTION
|
CDATA section not closed correctly
|
21
|
XML_ERROR_EXTERNAL_ENTITY_HANDLING
|
Error in processing external entity reference
|
In order to illustrate how this error-handling works, consider Listing 2.19, which contains a badly formed XML document. (There's a duplicate attribute within the element <circle>.) Note that the xml_error_string() function has been used to return a more helpful description of the error.
Listing 2.19 Better Error Handling
<html> <head> <basefont face="Arial"> </head> <body> <?php // XML data $xml_data = <<<EOF <?xml version="1.0"?> <shape> <circle color="red" radius="5" x="14" y="574" color="red" /> </shape> EOF; // define handlers function startElementHandler($parser, $name, $attributes) { // code snipped out } function endElementHandler($parser, $name) { // code snipped out } // initialize parser $xml_parser = xml_parser_create(); // set callback functions xml_set_element_handler ($xml_parser, "startElementHandler", "endElementHandler"); if (!xml_parse($xml_parser, $xml_data)) { $ec = xml_get_error_code($xml_parser); die("XML parser error (error code $ec): " . xml_error_string($ec)); } // all done, clean up! xml_parser_free($xml_parser); ?> </body> </html>
Why stop there? It's also possible to include information on where exactly the error occurred within the document, with these three built-in functions:
xml_get_current_line_number() Returns the current line number
xml_get_current_column_number() Returns the current column number
xml_get_current_byte_index() Returns the current byte offset
Listing 2.20 is the revised script that incorporates this information.
Listing 2.20 Adding Line and Column Information to Error Messages
<html> <head> <basefont face="Arial"> </head> <body> <?php // XML data $xml_data = <<<EOF <?xml version="1.0"?> <shape> <circle color="red" radius="5" x="14" y="574" color="red" /> </shape> EOF; // define handlers function startElementHandler($parser, $name, $attributes) { // code snipped out } function endElementHandler($parser, $name) { // code snipped out } // initialize parser $xml_parser = xml_parser_create(); // set callback functions xml_set_element_handler ($xml_parser, "startElementHandler", "endElementHandler"); if (!xml_parse($xml_parser, $xml_data)) { $ec = xml_get_error_code($xml_parser); die("XML parser error (error code $ec): " . xml_error_string($ec) . "<br>Error occurred at line " . xml_get_current _line_number($xml_parser) . ", column " . xml_get_current_column_number($xml_parser) . ", byte offset " . xml_get_current_byte_index($xml_parser)); } // all done, clean up! xml_parser_free($xml_parser); ?> </body> </html>
And here's the output:
XML parser error (error code 8): duplicate attribute Error occurred at line 3, column 46, byte offset 78
There! Isn't that much more helpful?
|