Add link m. blog. csdn. netarticledetails? Id7305068 is more practical, but has fewer concepts. The final role of DOM and SAX is to allow us to use javaJavaScript and other languages to obtain node, text, attributes, and other information in xml files. This article is introduced from other blogs, and the content is easy to understand. in order to save time, I copied it directly. Yangjunfeng. iteye. comblog40...
The final role of DOM and SAX is to allow us to use java JavaScript and other languages to obtain node, text, attributes, and other information in xml files.
This article is introduced from other blogs, and the content is easy to understand. in order to save time, I copied it directly. JAVA parses XML in two ways: DOM and SAX. Although DOM is W3C standard and provides a standard Parsing method, its parsing efficiency has been unsatisfactory because when using DOM to parse XML, the parser reads the entire document and constructs a tree (node tree) with resident memory. then, your code can use the standard DOM interface to operate the tree. However, in most cases, we are only interested in part of the content of the document, so we do not need to parse the entire document first, it is also time-consuming to index some data from the root node of the node tree.
SAX is an alternative to XML parsing. Compared with the Document Object Model DOM, SAX is a faster and lighter way to read and operate XML data.
Method. SAX allows you to process a document while reading it, so that you do not have to wait until the entire document is stored. It does not involve the overhead and concept jumps required by DOM. The sax api is an event-based API that is suitable for processing data streams, that is, processing data sequentially as data flows. SAX API
You will be notified when an event occurs when you parse your document. When you reply to the message, the data you do not save will be discarded.
The following is an example of how to parse XML by using SAX (a little long, because all methods for processing the SAX event are annotated in detail). There are four main event processing interfaces in the sax api, they are ContentHandler, DTDHandler, EntityResolver, and ErrorHandler. The example below may be a little lengthy. In fact, as long as the DefaultHandler class is inherited and a part of the event processing method is overwritten, the effect of this example can also be achieved, let's take a look at all the major event parsing methods in the sax api. (In fact, DefaultHandler implements the above four event processor interfaces, and then provides the default implementation of each abstract method .)
1. ContentHandler interface: the processor interface for receiving notifications of the logical content of a document.
Java code collection code
'Import org. xml. sax. Attributes;
Import org. xml. sax. ContentHandler;
Import org. xml. sax. Locator;
Import org. xml. sax. SAXException;
Class MyContentHandler implements ContentHandler {
StringBuffer jsonStringBuffer;
Int frontBlankCount = 0;
Public MyContentHandler (){
JsonStringBuffer = new StringBuffer ();
}
/*
* Receives notifications of character data.
* In the DOM, ch [begin: end] is equivalent to the nodeValue of the Text node)
*/
@ Override
Public void characters (char [] ch, int begin, int length) throws SAXException {
StringBuffer buffer = new StringBuffer ();
For (int I = begin; I <begin + length; I ++ ){
Switch (ch [I]) {
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\"); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ R ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\ r "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ n ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ n "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ t ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ t "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\"': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""); break;
Default: buffer. append (ch [I]);
}
}
System. out. println (this. toBlankString (this. frontBlankCount) +
">>> Characters (" + length + "):" + buffer. toString ());
}
/*
* Receive notifications at the end of a document.
*/
@ Override
Public void endDocument () throws SAXException {
System. out. println (this. toBlankString (-- this. frontBlankCount) +
">>> End document ");
}
/*
* Receive notifications at the end of a document.
* The parameter meaning is as follows:
* Uri: the namespace of the element.
* LocalName: the local name of the element (without the prefix)
* QName: the qualified name (with prefix) of the element)
*
*/
@ Override
Public void endElement (String uri, String localName, String qName)
Throws SAXException {
System. out. println (this. toBlankString (-- this. frontBlankCount) +
">>> End element:" + qName + "(" + uri + ")");
}
/*
* End the uri ing of the URI range prefix.
*/
@ Override
Public void endPrefixMapping (String prefix) throws SAXException {
System. out. println (this. toBlankString (-- this. frontBlankCount) +
">>> End prefix_mapping:" + prefix );
}
/*
* Receives blank notifications that can be ignored in the element content.
* The parameter meaning is as follows:
* Ch: characters from XML documents
* Start: start position in the array
* Length: the number of characters read from the array.
*/
@ Override
Public void ignorableWhitespace (char [] ch, int begin, int length)
Throws SAXException {
StringBuffer buffer = new StringBuffer ();
For (int I = begin; I <begin + length; I ++ ){
Switch (ch [I]) {
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\"); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ R ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\ r "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ n ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ n "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ t ': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ t "); break;
Case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\"': buffer. append ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""); break;
Default: buffer. append (ch [I]);
}
}
System. out. println (this. toBlankString (this. frontblkcount) + ">>> ignorable whitespace (" + length + "):" + buffer. toString ());
}
/*
* Receive notifications of processing commands.
* The parameter meaning is as follows:
* Target: process the command target
* Data: Process Command data. if not provided, it is null.
*/
@ Override
Public void processingInstruction (String target, String data)
Throws SAXException {
System. out. println (this. toBlankString (this. frontBlankCount) + ">>> process instruction: (target = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\""
+ Target + "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\", data = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ "" + data + "\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\") ");
}
/*
* Receives the object used to find the origin of the SAX document event.
* The parameter meaning is as follows:
* Locator: an object that can return any event location of a SAX document
*/
@ Override
Public void setDocumentLocator (Locator locator ){
System. out. println (this. toBlankString (this. frontBlankCount) +
">>> Set document_locator: (lineNumber =" + locator. getLineNumber ()
+ ", ColumnNumber =" + locator. getColumnNumber ()
+ ", SystemId =" + locator. getSystemId ()
+ ", PublicId =" + locator. getPublicId () + ")");
}
/*
* Receives notifications of skipped objects.
* The parameter meaning is as follows:
* Name: name of the skipped object. If it is a parameter entity, the name will start with '%,
* If it is an external DTD subset, it will be a string "[dtd]"
*/
@ Override
Public void skippedEntity (String name) throws SAXException {
System. out. println (this. toBlankString (this. frontBlankCount) +
">>> Skipped_entity:" + name );
}
/*
* Receives notifications of the beginning of a document.
*/
@ Override
Public void startDocument () throws SAXException {
System. out. println (this. toBlankString (this. frontBlankCount ++) +
">>> Start document ");
}
/*
* Receives notifications starting with an element.
* The parameter meaning is as follows:
* Uri: the namespace of the element.
* LocalName: the local name of the element (without the prefix)
* QName: the qualified name (with prefix) of the element)
* Atts: an attribute set of an element.
*/
@ Override
Public void startElement (String uri, String localName, String qName,
Attributes atts) throws SAXException {
System. out. println (this. toBlankString (this. frontBlankCount ++) +
">>> Start element:" + qName + "(" + uri + ")");
}
/*
* Start the prefix URI namespace range ING.
* The event information is not required for normal namespace processing:
* When the http://xml.org/sax/features/namespaces function is true (default,
* The sax xml reader automatically replaces the prefix of the element and attribute name.
* The parameter meaning is as follows:
* Prefix: prefix
* Uri: namespace
*/
@ Override
Public void startPrefixMapping (String prefix, String uri)
Throws SAXException {
System. out. println (this. toBlankString (this. frontBlankCount ++) +
">>> Start prefix_mapping: xmlns:" + prefix + "="
+ "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ "" + Uri + "\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\"");
}
Private String toBlankString (int count ){
StringBuffer buffer = new StringBuffer ();
For (int I = 0; I
Buffer. append ("");
Return buffer. toString ();
}
}'
2. DTDHandler interface: the processor interface for receiving notifications for DTD-related events.
Java code collection code
'Import org. xml. sax. DTDHandler;
Import org. xml. sax. SAXException;
Public class MyDTDHandler implements DTDHandler {
/*
* Receives notifications of comments and declarations.
* The parameter meaning is as follows:
* Name-comment name.
* PublicId-public identifier of the comment. if not provided, it is null.
* SystemId-annotation system identifier. if not provided, it is null.
*/
@ Override
Public void notationDecl (String name, String publicId, String systemId)
Throws SAXException {
System. out. println (">>> notation declare: (name =" + name
+ ", SystemId =" + publicId
+ ", PublicId =" + systemId + ")");
}
/*
* Receive notifications of unresolved entity declaration events.
* The parameter meaning is as follows:
* Name-the name of the unresolved object.
* PublicId-public identifier of the object. if not provided, it is null.
* SystemId-system identifier of the object.
* NotationName-name of the related comment.
*/
@ Override
Public void unparsedEntityDecl (String name,
String publicId,
String systemId,
String notationName) throws SAXException {
System. out. println (">>> unparsed entity declare: (name =" + name
+ ", SystemId =" + publicId
+ ", PublicId =" + systemId
+ ", NotationName =" + notationName + ")");
}
}'
3. EntityResolver interface: it is the basic interface used to parse objects.
Java code collection code
'Import java. io. IOException;
Import org. xml. sax. EntityResolver;
Import org. xml. sax. InputSource;
Import org. xml. sax. SAXException;
Public class MyEntityResolver implements EntityResolver {
/*
* Allow applications to parse external entities.
* The parser will call this method before opening any external entity (except the top-level document entity ).
* The parameter meaning is as follows:
* PublicId: public identifier of the referenced external entity. if not provided, it is null.
* SystemId: The system identifier of the referenced external entity.
* Return value:
* An InputSource object describing the new input source, or null is returned,
* Open the regular URI connection to the system identifier with the request parser.
*/
@ Override
Public InputSource resolveEntity (String publicId, String systemId)
Throws SAXException, IOException {
Return null;
}
}
4. ErrorHandler interface: it is the basic interface of the error handling program.
Java code collection code
Import org. xml. sax. ErrorHandler;
Import org. xml. sax. SAXException;
Import org. xml. sax. SAXParseException;
Public class MyErrorHandler implements ErrorHandler {
/*
* Receive recoverable error notifications
*/
@ Override
Public void error (SAXParseException e) throws SAXException {
System. err. println ("Error (" + e. getLineNumber () + ","
+ E. getColumnNumber () + "):" + e. getMessage ());
}
/*
* Receive unrecoverable error notifications.
*/
@ Override
Public void fatalError (SAXParseException e) throws SAXException {
System. err. println ("FatalError (" + e. getLineNumber () + ","
+ E. getColumnNumber () + "):" + e. getMessage ());
}
/*
* Receive unrecoverable error notifications.
*/
@ Override
Public void warning (SAXParseException e) throws SAXException {
System. err. println ("Warning (" + e. getLineNumber () + ","
+ E. getColumnNumber () + "):" + e. getMessage ());
}
}
The main method of the Test class prints the event information when parsing books. xml.
Java code collection code
Import java. io. FileNotFoundException;
Import java. io. FileReader;
Import java. io. IOException;
Import org. xml. sax. ContentHandler;
Import org. xml. sax. DTDHandler;
Import org. xml. sax. EntityResolver;
Import org. xml. sax. ErrorHandler;
Import org. xml. sax. InputSource;
Import org. xml. sax. SAXException;
Import org. xml. sax. XMLReader;
Import org. xml. sax. helpers. XMLReaderFactory;
Public class Test {
Public static void main (String [] args) throws SAXException,
FileNotFoundException, IOException {
// Create a processor to process document content-related events
ContentHandler contentHandler = new MyContentHandler ();
// Create a processing error event processor
ErrorHandler errorHandler = new MyErrorHandler ();
// Create a processor for processing DTD-related events
DTDHandler dtdHandler = new MyDTDHandler ();
// Create an object parser
EntityResolver entityResolver = new MyEntityResolver ();
// Create an XML parser (read and parse XML using the SAX method)
XMLReader reader = XMLReaderFactory. createXMLReader ();
/*
* Set the attributes of the parser.
* Http://xml.org/sax/features/validation = true indicates that verification feature is enabled
* Http://xml.org/sax/features/namespaces = true indicates that the namespace feature is enabled
*/
Reader. setFeature ("http://xml.org/sax/features/validation", true );
Reader. setFeature ("http://xml.org/sax/features/namespaces", true );
// Set the processor for processing document content-related events of the XML parser
Reader. setContentHandler (contentHandler );
// Set the processing error event processor for the XML parser
Reader. setErrorHandler (errorHandler );
// Set the processor for processing DTD-related events of the XML parser
Reader. setDTDHandler (dtdHandler );
// Set the object parser of the XML parser
Reader. setEntityResolver (entityResolver );
// Parse the books. xml document
Reader. parse (new InputSource (new FileReader ("books. xml ")));
}
}'
The content of the books. xml file is as follows:
Add Xml code to favorites
Thinking in JAVA
Core JAVA2
C ++ primer
The console output is as follows:
>>> Set document_locator: (lineNumber = 1, columnNumber = 1, systemId = null, publicId = null)
>>> Start document
Error (2, 7): Document is invalid: no grammar found.
Error (2, 7): Document root element "books", must match DOCTYPE root "null ".
>>> Start prefix_mapping: xmlns: = "http://test.org/books"
>>> Start element: books (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> Start element: book (http://test.org/books)
>>> Characters (3 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\ t \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ t
>>> Start element: name (http://test.org/books)
>>> Characters (16): Thinking in JAVA
>>> End element: name (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> End element: book (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> Start element: book (http://test.org/books)
>>> Characters (3 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\ t \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ t
>>> Start element: name (http://test.org/books)
>>> Characters (10): Core JAVA2
>>> End element: name (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> End element: book (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> Start element: book (http://test.org/books)
>>> Characters (3 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\ t \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ t
>>> Start element: name (http://test.org/books)
>>> Characters (10): C ++ primer
>>> End element: name (http://test.org/books)
>>> Characters (2 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ n \\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\ t
>>> End element: book (http://test.org/books)
>>> Characters (1 ): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\ n
>>> End element: books (http://test.org/books)
>>> End prefix_mapping:
>>> End document
The above is the detailed explanation of xml sax parsing. For more details, please refer to other related articles in the first PHP community!