Parser Capabilities and Architecture

There are two general approaches to parsing and handling XML, each with its own style of API:

The NSXMLParser class adopts the event-driven style of parsing. But instead of using callbacks, an NSXMLParser object (or simply, a parser) sends messages to its delegate; it sends a different message for each type of parsing event. As the parser sequentially encounters each item in an XML or DTD file—element, attribute, declaration, entity reference, and so on—it reports it to its delegate (if the delegate implements the associated method), along with any surrounding context. It does nothing with the item except report it.

For example, say you have a simple XML file such as the following:

<?xml version= “1.0” encoding=”UTF8”>
<article author=”John Doe”>
    <para>This is a very short article.</para>
</article>

The parser would report the following series of events to its delegate:

  1. Started parsing document

  2. Found start tag for element article

  3. Found attribute author of element article, value “John Doe”

  4. Found start tag for element para

  5. Found characters This is a very short article.

  6. Found end tag for element para

  7. Found end tag for element article

  8. Ended parsing document

Both the tree-based and event-based parsing approaches have their strengths and disadvantages. It can require considerable amounts of memory to construct an internal tree representing an XML document, especially if that document is large. This problem is compounded if it becomes necessary to map the tree structure of the parsed document to a more strongly typed, application-specific tree structure.

Event-driven parsing—because it deals with only one XML construct at a time and not all of them at once—consumes much less memory than tree-based parsing. It is ideal for situations where performance is a goal and modification of the parsed XML is not. One such application for event-driven parsing is searching a repository of XML documents (or even one XML document with multiple “records”) for specific elements and doing something with the element content. For example, you could use NSXMLParser to search the property-list preferences files on all machines in a Bonjour network to gather network-configuration information.

Event-driven parsing is less suitable for tasks that require the XML to be subjected to extended user queries or to be modified and written back to a file. Event-driven parsers such as NSXMLParser also do not offer any help with validation (that is, it verifying whether XML conforms to the structuring rules as specified in a DTD or other schema). For these kinds of tasks, you need a DOM-style tree. However, you can construct your own internal tree structures using an event-driven parser such as NSXMLParser.

In addition to reporting parsing events, an NSXMLParser object verifies that the XML or DTD is well-formed. For example, it checks whether a start tag for an element has a matching end tag or whether an attribute has a value assigned. If it encounters any such syntactical error, it stops parsing and informs the delegate.

Although the parser “understands” only XML and DTD as markup languages, it can parse any XML-based language schema such as RELAX NG and XML Schema.