//
// ContentHandler.h
//
// Library: XML
// Package: SAX
// Module:  SAX
//
// SAX2 ContentHandler Interface.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef SAX_ContentHandler_INCLUDED
#define SAX_ContentHandler_INCLUDED


#include "Poco/XML/XML.h"
#include "Poco/XML/XMLString.h"


namespace Poco {
namespace XML {


class Locator;
class Attributes;


class XML_API ContentHandler
	/// Receive notification of the logical content of a document.
	///
	/// This is the main interface that most SAX applications implement: if the
	/// application needs to be informed of basic parsing events, it implements
	/// this interface and registers an instance with the SAX parser using the setContentHandler
	/// method. The parser uses the instance to report basic document-related events
	/// like the start and end of elements and character data.
	///
	/// The order of events in this interface is very important, and mirrors the
	/// order of information in the document itself. For example, all of an element's
	/// content (character data, processing instructions, and/or subelements) will
	/// appear, in order, between the startElement event and the corresponding endElement
	/// event.
	///
	/// This interface is similar to the now-deprecated SAX 1.0 DocumentHandler
	/// interface, but it adds support for Namespaces and for reporting skipped
	/// entities (in non-validating XML processors).
	/// Receive notification of the logical content of a document.
{
public:
	virtual void setDocumentLocator(const Locator* loc) = 0;
		/// Receive an object for locating the origin of SAX document events.
		///
		/// SAX parsers are strongly encouraged (though not absolutely required) to
		/// supply a locator: if it does so, it must supply the locator to the application
		/// by invoking this method before invoking any of the other methods in the
		/// ContentHandler interface.
		///
		/// The locator allows the application to determine the end position of any
		/// document-related event, even if the parser is not reporting an error. Typically,
		/// the application will use this information for reporting its own errors (such
		/// as character content that does not match an application's business rules).
		/// The information returned by the locator is probably not sufficient for use
		/// with a search engine.
		///
		/// Note that the locator will return correct information only during the invocation
		/// SAX event callbacks after startDocument returns and before endDocument is
		/// called. The application should not attempt to use it at any other time.

	virtual void startDocument() = 0;
		/// Receive notification of the beginning of a document.
		///
		/// The SAX parser calls this function one time before calling all other
		/// functions of this class (except SetDocumentLocator).

	virtual void endDocument() = 0;
		/// Receive notification of the end of a document.
		///
		/// The SAX parser will invoke this method only once, and it will be the last
		/// method invoked during the parse. The parser shall not invoke this method
		/// until it has either abandoned parsing (because of an unrecoverable error)
		/// or reached the end of input.

	virtual void startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attrList) = 0;
		/// Receive notification of the beginning of an element.
		///
		/// The Parser will invoke this method at the beginning of every element in
		/// the XML document; there will be a corresponding endElement event for every
		/// startElement event (even when the element is empty). All of the element's
		/// content will be reported, in order, before the corresponding endElement
		/// event.
		///
		/// This event allows up to three name components for each element:
		///    1. the Namespace URI;
		///    2. the local name; and
		///    3. the qualified (prefixed) name.
		///
		/// Any or all of these may be provided, depending on the values of the http://xml.org/sax/features/namespaces
		/// and the http://xml.org/sax/features/namespace-prefixes properties:
		///     * the Namespace URI and local name are required when the namespaces
		///       property is true (the default), and are optional when the namespaces property
		///       is false (if one is specified, both must be);
		///     * the qualified name is required when the namespace-prefixes property
		///       is true, and is optional when the namespace-prefixes property is false (the
		///       default).
		///
		/// Note that the attribute list provided will contain only attributes with
		/// explicit values (specified or defaulted): #IMPLIED attributes will be omitted.
		/// The attribute list will contain attributes used for Namespace declarations
		/// (xmlns* attributes) only if the http://xml.org/sax/features/namespace-prefixes
		/// property is true (it is false by default, and support for a true value is
		/// optional).
		///
		/// Like characters(), attribute values may have characters that need more than
		/// one char value.

	virtual void endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname) = 0;
		/// Receive notification of the end of an element.
		///
		/// The SAX parser will invoke this method at the end of every element in the
		/// XML document; there will be a corresponding startElement event for every
		/// endElement event (even when the element is empty).
		///
		/// For information on the names, see startElement.

	virtual void characters(const XMLChar ch[], int start, int length) = 0;
		/// Receive notification of character data.
		///
		/// The Parser will call this method to report each chunk of character data.
		/// SAX parsers may return all contiguous character data in a single chunk,
		/// or they may split it into several chunks; however, all of the characters
		/// in any single event must come from the same external entity so that the
		/// Locator provides useful information.
		///
		/// The application must not attempt to read from the array outside of the specified
		/// range.
		///
		/// Individual characters may consist of more than one XMLChar value. There
		/// are three important cases where this happens, because characters can't be
		/// represented in just sixteen bits. In one case, characters are represented
		/// in a Surrogate Pair, using two special Unicode values. Such characters are
		/// in the so-called "Astral Planes", with a code point above U+FFFF. A second
		/// case involves composite characters, such as a base character combining with
		/// one or more accent characters. And most important, if XMLChar is a plain
		/// char, characters are encoded in UTF-8.
		///
		/// Your code should not assume that algorithms using char-at-a-time idioms
		/// will be working in character units; in some cases they will split characters.
		/// This is relevant wherever XML permits arbitrary characters, such as attribute
		/// values, processing instruction data, and comments as well as in data reported
		/// from this method. It's also generally relevant whenever C++ code manipulates
		/// internationalized text; the issue isn't unique to XML.
		///
		/// Note that some parsers will report whitespace in element content using the
		/// ignorableWhitespace method rather than this one (validating parsers must
		/// do so).

	virtual void ignorableWhitespace(const XMLChar ch[], int start, int length) = 0;
		/// Receive notification of ignorable whitespace in element content.
		///
		/// Validating Parsers must use this method to report each chunk of whitespace
		/// in element content (see the W3C XML 1.0 recommendation, section 2.10): non-validating
		/// parsers may also use this method if they are capable of parsing and using
		/// content models.
		///
		/// SAX parsers may return all contiguous whitespace in a single chunk, or they
		/// may split it into several chunks; however, all of the characters in any
		/// single event must come from the same external entity, so that the Locator
		/// provides useful information.
		///
		/// The application must not attempt to read from the array outside of the specified
		/// range.

	virtual void processingInstruction(const XMLString& target, const XMLString& data) = 0;
		/// Receive notification of a processing instruction.
		///
		/// The Parser will invoke this method once for each processing instruction
		/// found: note that processing instructions may occur before or after the main
		/// document element.
		///
		/// A SAX parser must never report an XML declaration (XML 1.0, section 2.8)
		/// or a text declaration (XML 1.0, section 4.3.1) using this method.
		///
		/// Like characters(), processing instruction data may have characters that
		/// need more than one char value.

	virtual void startPrefixMapping(const XMLString& prefix, const XMLString& uri) = 0;
		/// Begin the scope of a prefix-URI Namespace mapping.
		///
		/// The information from this event is not necessary for normal Namespace processing:
		/// the SAX XML reader will automatically replace prefixes for element and attribute
		/// names when the http://xml.org/sax/features/namespaces feature is true (the
		/// default).
		///
		/// There are cases, however, when applications need to use prefixes in character
		/// data or in attribute values, where they cannot safely be expanded automatically;
		/// the start/endPrefixMapping event supplies the information to the application
		/// to expand prefixes in those contexts itself, if necessary.
		///
		/// Note that start/endPrefixMapping events are not guaranteed to be properly
		/// nested relative to each other: all startPrefixMapping events will occur
		/// immediately before the corresponding startElement event, and all endPrefixMapping
		/// events will occur immediately after the corresponding endElement event,
		/// but their order is not otherwise guaranteed.
		///
		/// There should never be start/endPrefixMapping events for the "xml" prefix,
		/// since it is predeclared and immutable.

	virtual void endPrefixMapping(const XMLString& prefix) = 0;
		/// End the scope of a prefix-URI mapping.
		///
		/// See startPrefixMapping for details. These events will always occur immediately
		/// after the corresponding endElement event, but the order of endPrefixMapping
		/// events is not otherwise guaranteed.

	virtual void skippedEntity(const XMLString& name) = 0;
		/// Receive notification of a skipped entity. This is not called for entity
		/// references within markup constructs such as element start tags or markup
		/// declarations. (The XML recommendation requires reporting skipped external
		/// entities. SAX also reports internal entity expansion/non-expansion, except
		/// within markup constructs.)
		///
		/// The Parser will invoke this method each time the entity is skipped. Non-validating
		/// processors may skip entities if they have not seen the declarations (because,
		/// for example, the entity was declared in an external DTD subset). All processors
		/// may skip external entities, depending on the values of the http://xml.org/sax/features/external-general-entities
		/// and the http://xml.org/sax/features/external-parameter-entities properties.

protected:
	virtual ~ContentHandler();
};


} } // namespace Poco::XML


#endif // SAX_ContentHandler_INCLUDED
